목록에서 여러 요소 삭제
목록에서 여러 요소를 동시에 삭제할 수 있습니까?인덱스 0과 2의 요소를 삭제하고 다음과 같은 작업을 수행합니다.del somelist[0]
에 뒤에del somelist[2]
두번진은실삭것입제다니될제로술째다것▁actually▁will를 삭제합니다.somelist[3]
.
번호가 높은 요소는 항상 먼저 삭제할 수 있지만 더 좋은 방법이 있기를 바랍니다.
어떤 이유에서인지 저는 여기에 있는 어떤 대답도 좋아하지 않습니다.네, 작동하지만 엄밀히 말하면 대부분은 목록의 요소를 삭제하는 것은 아닙니다. (그러나 복사본을 만든 다음 원본을 편집된 복사본으로 바꿉니다.)
먼저 상위 지수를 삭제하는 것이 어떻습니까?
이것에 대한 이유가?저는 그냥 할 것입니다.
for i in sorted(indices, reverse=True):
del somelist[i]
항목을 역방향으로 삭제하지 않으려면 마지막으로 삭제한 인덱스보다 큰 인덱스 값(다른 목록이 있으므로 동일한 인덱스를 사용할 수 없음)을 감소시키거나 목록 복사본을 사용해야 합니다('삭제'가 아니라 편집된 복사본으로 원본을 대체).
제가 여기서 누락된 것이 있습니까, 역순으로 삭제하지 않을 이유가 있습니까?
사용할 수 있습니다.enumerate
제거할 인덱스와 일치하는 인덱스 값을 제거합니다.
indices = 0, 2
somelist = [i for j, i in enumerate(somelist) if j not in indices]
인접하지 않은 여러 항목을 삭제하는 경우 설명하는 것이 가장 좋습니다(가장 높은 인덱스에서 시작해야 함).
항목이 인접한 경우 슬라이스 할당 구문을 사용할 수 있습니다.
a[2:10] = []
사용할 수 있습니다.numpy.delete
다음과 같이:
import numpy as np
a = ['a', 'l', 3.14, 42, 'u']
I = [0, 2]
np.delete(a, I).tolist()
# Returns: ['l', '42', 'u']
만약 당신이 괜찮다면, 마지막에.numpy
은 지막에배, ▁leave▁at▁array를 생략할 수 있습니다..tolist()
이 솔루션을 보다 확장 가능한 솔루션으로 만들기 위해 속도가 상당히 크게 개선되었습니다.안 , 벤치킹안해만지봤은마,만해▁i지봤▁but안,벤ed▁it.numpy
연산은 C 또는 Fortran으로 작성된 코드를 컴파일합니다.
Greg의 답변 전문으로서 확장 슬라이스 구문을 사용할 수도 있습니다.항목 0 및 2를 삭제하려면 다음을 수행합니다.
>>> a= [0, 1, 2, 3, 4]
>>> del a[0:3:2]
>>> a
[1, 3, 4]
물론 임의로 선택한 항목은 포함되지 않지만 두 항목을 삭제하는 데 사용할 수 있습니다.
함수로서:
def multi_delete(list_, *args):
indexes = sorted(list(args), reverse=True)
for index in indexes:
del list_[index]
return list_
nlog(n) 시간 내에 실행되므로 지금까지 가장 빠른 올바른 솔루션입니다.
그러면 기본적으로 한 번에 여러 요소를 삭제하시겠습니까?이 경우 삭제할 다음 요소의 위치는 이전에 삭제된 요소의 수에 따라 상쇄됩니다.
우리의 목표는 색인 1, 4, 7로 사전 계산된 모든 모음을 삭제하는 것입니다.to_delete 인덱스가 오름차순으로 정렬되어 있어야 합니다. 그렇지 않으면 작동하지 않습니다.
to_delete = [1, 4, 7]
target = list("hello world")
for offset, index in enumerate(to_delete):
index -= offset
del target[index]
어떤 순서로든 요소를 삭제하려면 더 복잡합니다.IMO, 정렬to_delete
언제 뺄지 안 뺄지 알아내는 것보다 쉬울 수도 있습니다.index
.
저는 파이썬의 완전한 초보자이고, 현재 제 프로그래밍은 아무리 말해도 거칠고 더럽지만, 제 해결책은 초기 튜토리얼에서 배운 기본 명령어를 조합하여 사용하는 것이었습니다.
some_list = [1,2,3,4,5,6,7,8,10]
rem = [0,5,7]
for i in rem:
some_list[i] = '!' # mark for deletion
for i in range(0, some_list.count('!')):
some_list.remove('!') # remove
print some_list
분명히, "삭제 표시" 문자를 선택해야 하기 때문에, 이것은 한계가 있습니다.
목록의 크기가 확장되는 성능에 대해서는 제 솔루션이 차선이라고 확신합니다.하지만, 그것은 간단하고, 나는 다른 초보자들에게 어필하기를 바라며, 간단한 경우에 효과가 있을 것입니다.some_list
는 잘 알려진 형식입니다. 예를 들어 항상 숫자로 표시됩니다.
여기에 열거형()을 사용하여 튜플을 만들지 않는 대안이 있습니다(사일런트 고스트의 원래 답변에서처럼).
제가 보기에 이것이 더 읽기 쉬운 것 같습니다. (아마도 제가 열거형을 사용하는 습관이 있었다면 다르게 느꼈을 것입니다.) 주의:저는 두 가지 접근법의 성능을 테스트하지 않았습니다.
# Returns a new list. "lst" is not modified.
def delete_by_indices(lst, indices):
indices_as_set = set(indices)
return [ lst[i] for i in xrange(len(lst)) if i not in indices_as_set ]
파일: Python 2.7 파일.3, Python 3의 xrange
=>range
.
용도:
lst = [ 11*x for x in xrange(10) ]
somelist = delete_by_indices( lst, [0, 4, 5])
일부 목록:
[11, 22, 33, 66, 77, 88, 99]
보너스 ---
목록에서 여러 값을 삭제합니다.즉, 삭제할 값이 있습니다.
# Returns a new list. "lst" is not modified.
def delete__by_values(lst, values):
values_as_set = set(values)
return [ x for x in lst if x not in values_as_set ]
용도:
somelist = delete__by_values( lst, [0, 44, 55] )
일부 목록:
[11, 22, 33, 66, 77, 88, 99]
했습니다.[0, 44, 55]
.
목록 인덱스 값을 사용하는 대체 목록 이해 방법:
stuff = ['a', 'b', 'c', 'd', 'e', 'f', 'woof']
index = [0, 3, 6]
new = [i for i in stuff if stuff.index(i) not in index]
다음이 반환됩니다.
['b', 'c', 'e', 'f']
여기 제 자리에 있는 요소를 제거하는 다른 방법이 있습니다.또한 만약 당신의 목록이 정말 길다면, 그것은 더 빠릅니다.
>>> a = range(10)
>>> remove = [0,4,5]
>>> from collections import deque
>>> deque((list.pop(a, i) for i in sorted(remove, reverse=True)), maxlen=0)
>>> timeit.timeit('[i for j, i in enumerate(a) if j not in remove]', setup='import random;remove=[random.randrange(100000) for i in range(100)]; a = range(100000)', number=1)
0.1704120635986328
>>> timeit.timeit('deque((list.pop(a, i) for i in sorted(remove, reverse=True)), maxlen=0)', setup='from collections import deque;import random;remove=[random.randrange(100000) for i in range(100)]; a = range(100000)', number=1)
0.004853963851928711
이것은 언급되었지만, 어떻게든 아무도 그것을 제대로 맞추지 못했습니다.
O(n)
해결책은 다음과 같습니다.
indices = {0, 2}
somelist = [i for j, i in enumerate(somelist) if j not in indices]
이것은 사일런트 고스트의 버전에 매우 가깝지만, 두 개의 교정기를 추가합니다.
l = ['a','b','a','c','a','d']
to_remove = [1, 3]
[l[i] for i in range(0, len(l)) if i not in to_remove])
그것은 기본적으로 상위 투표된 답변과 동일하며, 단지 그것을 쓰는 다른 방법입니다.목록에서 중복된 요소를 처리할 수 없으므로 l.index()를 사용하는 것은 좋지 않습니다.
제거 방법을 사용하면 목록 요소가 많이 이동합니다.저는 복사본을 만드는 것이 더 낫다고 생각합니다.
...
new_list = []
for el in obj.my_list:
if condition_is_true(el):
new_list.append(el)
del obj.my_list
obj.my_list = new_list
...
기술적으로 두 개체를 동시에 삭제할 수 없습니다.그러나 아름다운 파이썬의 한 줄에서 두 개의 객체를 삭제하는 것은 가능합니다.
del (foo['bar'],foo['baz'])
으로 삭제합니다.foo['bar']
,그리고나서foo['baz']
인덱스 목록을 내림차순으로 정렬한 후 인덱스 위에서 반복되는 for 루프를 사용하여 이 작업을 수행할 수 있습니다.
mylist=[66.25, 333, 1, 4, 6, 7, 8, 56, 8769, 65]
indexes = 4,6
indexes = sorted(indexes, reverse=True)
for i in index:
mylist.pop(i)
print mylist
리스트의 지수 0과 2의 경우A:
for x in (2,0): listA.pop(x)
목록 A에서 제거할 일부 랜덤 인덱스의 경우:
indices=(5,3,2,7,0)
for x in sorted(indices)[::-1]: listA.pop(x)
저는 손잡이를 쉽게 돌릴 수 있는 다양한 솔루션을 비교하는 방법을 원했습니다.
처음에 데이터를 생성했습니다.
import random
N = 16 * 1024
x = range(N)
random.shuffle(x)
y = random.sample(range(N), N / 10)
그런 다음 제 기능을 정의했습니다.
def list_set(value_list, index_list):
index_list = set(index_list)
result = [value for index, value in enumerate(value_list) if index not in index_list]
return result
def list_del(value_list, index_list):
for index in sorted(index_list, reverse=True):
del(value_list[index])
def list_pop(value_list, index_list):
for index in sorted(index_list, reverse=True):
value_list.pop(index)
그다음에 제가.timeit
솔루션 비교:
import timeit
from collections import OrderedDict
M = 1000
setup = 'from __main__ import x, y, list_set, list_del, list_pop'
statement_dict = OrderedDict([
('overhead', 'a = x[:]'),
('set', 'a = x[:]; list_set(a, y)'),
('del', 'a = x[:]; list_del(a, y)'),
('pop', 'a = x[:]; list_pop(a, y)'),
])
overhead = None
result_dict = OrderedDict()
for name, statement in statement_dict.iteritems():
result = timeit.timeit(statement, number=M, setup=setup)
if overhead is None:
overhead = result
else:
result = result - overhead
result_dict[name] = result
for name, result in result_dict.iteritems():
print "%s = %7.3f" % (name, result)
산출량
set = 1.711
del = 3.450
pop = 3.618
가 래서인지생인 set
우승자였습니다.그리고.del
약간빠다니보다 약간 빠릅니다.pop
.
다음 논리를 사용할 수 있습니다.
my_list = ['word','yes','no','nice']
c=[b for i,b in enumerate(my_list) if not i in (0,2,3)]
print c
가장 높은 지수에서 제거하는 아이디어의 또 다른 구현입니다.
for i in range(len(yourlist)-1, -1, -1):
del yourlist(i)
np.delete를 사용하면 됩니다.
list_indices = [0, 2]
original_list = [0, 1, 2, 3]
new_list = np.delete(original_list, list_indices)
산출량
array([1, 3])
여기서 첫 번째 인수는 원본 목록이고 두 번째 인수는 삭제할 인덱스 또는 인덱스 목록입니다.
ndarray가 있는 경우 사용할 수 있는 세 번째 인수가 있습니다. axis(행은 0, ndarray는 열은 1)
저는 실제로 두 가지 방법을 생각할 수 있습니다.
목록을 다음과 같이 자릅니다(첫 번째, 세 번째 및 여덟 번째 요소가 삭제됨).
someelist = someelist [1:2] + someelist [3:7] + someelist [8:]
한 번에 하나씩 수행합니다.
someelist.pop(2) someelist.pop(0)
리스트가 아닌 딕트로 그렇게 할 수 있습니다.목록에서 요소는 순서대로 나열됩니다.딕트에서는 인덱스에만 의존합니다.
다음을 수행하여 간단히 설명할 수 있는 코드:
>>> lst = ['a','b','c']
>>> dct = {0: 'a', 1: 'b', 2:'c'}
>>> lst[0]
'a'
>>> dct[0]
'a'
>>> del lst[0]
>>> del dct[0]
>>> lst[0]
'b'
>>> dct[0]
Traceback (most recent call last):
File "<pyshell#19>", line 1, in <module>
dct[0]
KeyError: 0
>>> dct[1]
'b'
>>> lst[1]
'c'
딕트에서 목록을 "변환"하는 방법은 다음과 같습니다.
>>> dct = {}
>>> for i in xrange(0,len(lst)): dct[i] = lst[i]
그 반대는 다음과 같습니다.
lst = [dct[i] for i in sorted(dct.keys())]
어쨌든 말씀하신 대로 상위 인덱스에서 삭제를 시작하는 것이 좋을 것 같습니다.
@thh의 설명을 일반화합니다.abc를 구현하는 모든 클래스의 항목 삭제.가변 시퀀스, 그리고list
는 특히, 을통수니다됩행해를 통해 .__delitem__
마술적인 방법이 방법은 다음과 유사하게 작동합니다.__getitem__
즉, 정수 또는 조각을 허용할 수 있습니다.다음은 예입니다.
class MyList(list):
def __delitem__(self, item):
if isinstance(item, slice):
for i in range(*item.indices(len(self))):
self[i] = 'null'
else:
self[item] = 'null'
l = MyList(range(10))
print(l)
del l[5:8]
print(l)
출력됩니다.
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 'null', 'null', 'null', 8, 9]
될 수 , 라도 이한이가만기하면오발이버수, 사중인경우용만있러지생할킬유로져오▁importing▁you경우kill▁using▁only▁but,▁over중▁happen이▁it러▁be인사▁if▁to▁for.pandas
어쨌든, 그 해결책은 간단하고 간단합니다.
import pandas as pd
stuff = pd.Series(['a','b','a','c','a','d'])
less_stuff = stuff[stuff != 'a'] # define any condition here
# results ['b','c','d']
some_list.remove(some_list[max(i, j)])
정렬 비용이 들지 않고 목록을 명시적으로 복사하지 않아도 됩니다.
지금까지 제공된 답변 중 삭제할 임의 개수의 인덱스에 대해 목록 길이의 O(n)에 있는 삭제를 수행하는 답변이 없습니다. 따라서 제 버전은 다음과 같습니다.
def multi_delete(the_list, indices):
assert type(indices) in {set, frozenset}, "indices must be a set or frozenset"
offset = 0
for i in range(len(the_list)):
if i in indices:
offset += 1
elif offset:
the_list[i - offset] = the_list[i]
if offset:
del the_list[-offset:]
# Example:
a = [0, 1, 2, 3, 4, 5, 6, 7]
multi_delete(a, {1, 2, 4, 6, 7})
print(a) # prints [0, 3, 5]
제안된 솔루션을 perfplot으로 테스트한 결과 NumPy의
np.delete(lst, remove_ids)
목록이 약 100개의 항목보다 길 경우 가장 빠른 솔루션입니다.그 전에 모든 솔루션은 약 10^-5초입니다.그렇다면 목록 이해는 충분히 간단한 것 같습니다.
out = [item for i, item in enumerate(lst) if i not in remove_ids]
그림을 재현하는 코드:
import perfplot
import random
import numpy as np
import copy
def setup(n):
lst = list(range(n))
random.shuffle(lst)
# //10 = 10%
remove_ids = random.sample(range(n), n // 10)
return lst, remove_ids
def if_comprehension(lst, remove_ids):
return [item for i, item in enumerate(lst) if i not in remove_ids]
def del_list_inplace(lst, remove_ids):
out = copy.deepcopy(lst)
for i in sorted(remove_ids, reverse=True):
del out[i]
return out
def del_list_numpy(lst, remove_ids):
return np.delete(lst, remove_ids)
b = perfplot.bench(
setup=setup,
kernels=[if_comprehension, del_list_numpy, del_list_inplace],
n_range=[2**k for k in range(20)],
)
b.save("out.png")
b.show()
다음 중 하나는 어떻습니까(Python은 처음이지만 괜찮아 보입니다).
ocean_basin = ['a', 'Atlantic', 'Pacific', 'Indian', 'a', 'a', 'a']
for i in range(1, (ocean_basin.count('a') + 1)):
ocean_basin.remove('a')
print(ocean_basin)
['대서양', '태평양', '인도']
ob = ['a', 'b', 4, 5,'Atlantic', 'Pacific', 'Indian', 'a', 'a', 4, 'a']
remove = ('a', 'b', 4, 5)
ob = [i for i in ob if i not in (remove)]
print(ob)
['대서양', '태평양', '인도']
저는 그것을 모두 하나로 묶었습니다.list_diff
첫 번째 목록의 원래 순서를 유지하면서 두 개의 목록을 입력으로 사용하고 차이를 반환하는 함수입니다.
def list_diff(list_a, list_b, verbose=False):
# returns a difference of list_a and list_b,
# preserving the original order, unlike set-based solutions
# get indices of elements to be excluded from list_a
excl_ind = [i for i, x in enumerate(list_a) if x in list_b]
if verbose:
print(excl_ind)
# filter out the excluded indices, producing a new list
new_list = [i for i in list_a if list_a.index(i) not in excl_ind]
if verbose:
print(new_list)
return(new_list)
샘플 사용량:
my_list = ['a', 'b', 'c', 'd', 'e', 'f', 'woof']
# index = [0, 3, 6]
# define excluded names list
excl_names_list = ['woof', 'c']
list_diff(my_list, excl_names_list)
>> ['a', 'b', 'd', 'e', 'f']
언급URL : https://stackoverflow.com/questions/497426/deleting-multiple-elements-from-a-list
'programing' 카테고리의 다른 글
엑셀에서 두 날짜 타임스탬프의 시간과 분의 차이를 얻는 방법은 무엇입니까? (0) | 2023.05.18 |
---|---|
데이터베이스를 호출하는 방법 및 위치.작성 및 데이터베이스를 확인합니다.이주? (0) | 2023.05.18 |
ASP.NET MVC의 다른 컨트롤러에서 보기 표시 (0) | 2023.05.18 |
Xcode에서 "작업관리" 주석을 어떻게 표시합니까? (0) | 2023.05.13 |
Xcode 프로젝트 이름 변경 방법 (0) | 2023.05.13 |