Câu trả lời:
Phương pháp chức năng:
Python 3.x
>>> x = [1,2,3,2,2,2,3,4]
>>> list(filter((2).__ne__, x))
[1, 3, 3, 4]
hoặc là
>>> x = [1,2,3,2,2,2,3,4]
>>> list(filter(lambda a: a != 2, x))
[1, 3, 3, 4]
Python 2.x
>>> x = [1,2,3,2,2,2,3,4]
>>> filter(lambda a: a != 2, x)
[1, 3, 3, 4]
[y for y in x if y != 2]
__ne__
. So sánh hai giá trị là một quá trình phức tạp hơn nhiều so với chỉ gọi __eq__
hoặc __ne__
trên một trong số chúng. Nó có thể hoạt động chính xác ở đây vì bạn chỉ so sánh các số, nhưng trong trường hợp chung đó không chính xác và là một lỗi.
Bạn có thể sử dụng một danh sách hiểu:
def remove_values_from_list(the_list, val):
return [value for value in the_list if value != val]
x = [1, 2, 3, 4, 2, 2, 3]
x = remove_values_from_list(x, 2)
print x
# [1, 3, 4, 3]
in
toán tử và remove
phương thức đều quét toàn bộ danh sách (cho đến khi chúng tìm thấy kết quả khớp) để cuối cùng bạn quét danh sách nhiều lần theo cách đó.
Bạn có thể sử dụng phép gán lát nếu danh sách gốc phải được sửa đổi, trong khi vẫn sử dụng cách hiểu danh sách hiệu quả (hoặc biểu thức trình tạo).
>>> x = [1, 2, 3, 4, 2, 2, 3]
>>> x[:] = (value for value in x if value != 2)
>>> x
[1, 3, 4, 3]
x = [ v for v in x if x != 2 ]
đề xuất, tạo ra một danh sách mới và thay đổi x để tham chiếu đến nó, khiến cho danh sách ban đầu không bị ảnh hưởng.
Lặp lại giải pháp của bài đầu tiên theo cách trừu tượng hơn:
>>> x = [1, 2, 3, 4, 2, 2, 3]
>>> while 2 in x: x.remove(2)
>>> x
[1, 3, 4, 3]
x = [1] * 10000 + [2] * 1000
. Phần thân vòng lặp thực thi 1000 lần và .remove () phải bỏ qua 10000 phần tử mỗi lần nó được gọi. Điều đó có mùi giống như O (n * n) đối với tôi nhưng không có bằng chứng. Tôi nghĩ bằng chứng sẽ là giả định rằng số lượng 2 trong danh sách tỷ lệ thuận với chiều dài của nó. Yếu tố tỷ lệ đó sau đó biến mất trong ký hiệu big-O. Tuy nhiên, trường hợp tốt nhất chỉ có số lượng 2 giây không đổi trong danh sách, không phải là O (n ^ 2), chỉ là O (2n) là O (n).
Tất cả các câu trả lời ở trên (ngoài Martin Andersson) tạo ra một danh sách mới mà không có các mục mong muốn, thay vì xóa các mục khỏi danh sách ban đầu.
>>> import random, timeit
>>> a = list(range(5)) * 1000
>>> random.shuffle(a)
>>> b = a
>>> print(b is a)
True
>>> b = [x for x in b if x != 0]
>>> print(b is a)
False
>>> b.count(0)
0
>>> a.count(0)
1000
>>> b = a
>>> b = filter(lambda a: a != 2, x)
>>> print(b is a)
False
Điều này có thể quan trọng nếu bạn có các tài liệu tham khảo khác cho danh sách treo xung quanh.
Để sửa đổi danh sách tại chỗ, sử dụng một phương pháp như thế này
>>> def removeall_inplace(x, l):
... for _ in xrange(l.count(x)):
... l.remove(x)
...
>>> removeall_inplace(0, b)
>>> b is a
True
>>> a.count(0)
0
Liên quan đến tốc độ, kết quả trên máy tính xách tay của tôi là (tất cả trong danh sách 5000 mục với 1000 mục đã bị xóa)
Vì vậy, vòng lặp .remove chậm hơn khoảng 100 lần ........ Hmmm, có thể cần một cách tiếp cận khác. Cách nhanh nhất tôi tìm thấy là sử dụng khả năng hiểu danh sách, nhưng sau đó thay thế nội dung của danh sách ban đầu.
>>> def removeall_replace(x, l):
.... t = [y for y in l if y != x]
.... del l[:]
.... l.extend(t)
def remove_all(x, l): return [y for y in l if y != x]
sau đól = remove_all(3,l)
bạn có thể làm được việc này
while 2 in x:
x.remove(2)
Với chi phí dễ đọc, tôi nghĩ phiên bản này nhanh hơn một chút vì nó không bắt buộc phải xem lại danh sách, do đó thực hiện chính xác cùng một công việc loại bỏ phải thực hiện:
x = [1, 2, 3, 4, 2, 2, 3]
def remove_values_from_list(the_list, val):
for i in range(the_list.count(val)):
the_list.remove(val)
remove_values_from_list(x, 2)
print(x)
Cách tiếp cận và thời gian gọn gàng đối với một danh sách / mảng với 1.000.000 phần tử:
Thời gian:
In [10]: a.shape
Out[10]: (1000000,)
In [13]: len(lst)
Out[13]: 1000000
In [18]: %timeit a[a != 2]
100 loops, best of 3: 2.94 ms per loop
In [19]: %timeit [x for x in lst if x != 2]
10 loops, best of 3: 79.7 ms per loop
Kết luận: numpy nhanh hơn 27 lần (trên máy tính xách tay của tôi) so với phương pháp hiểu danh sách
PS nếu bạn muốn chuyển đổi danh sách Python thông thường của mình lst
sang mảng numpy:
arr = np.array(lst)
Thiết lập:
import numpy as np
a = np.random.randint(0, 1000, 10**6)
In [10]: a.shape
Out[10]: (1000000,)
In [12]: lst = a.tolist()
In [13]: len(lst)
Out[13]: 1000000
Kiểm tra:
In [14]: a[a != 2].shape
Out[14]: (998949,)
In [15]: len([x for x in lst if x != 2])
Out[15]: 998949
a = [1, 2, 2, 3, 1]
to_remove = 1
a = [i for i in a if i != to_remove]
print(a)
Có lẽ không phải là pythonic nhất nhưng vẫn dễ nhất đối với tôi haha
Để xóa tất cả các lần xuất hiện trùng lặp và để lại một trong danh sách:
test = [1, 1, 2, 3]
newlist = list(set(test))
print newlist
[1, 2, 3]
Đây là chức năng tôi đã sử dụng cho Project Euler:
def removeOccurrences(e):
return list(set(e))
Tôi tin rằng điều này có thể nhanh hơn bất kỳ cách nào khác nếu bạn không quan tâm đến thứ tự danh sách, nếu bạn quan tâm đến đơn hàng cuối cùng lưu trữ các chỉ mục từ bản gốc và khu nghỉ mát bằng cách đó.
category_ids.sort()
ones_last_index = category_ids.count('1')
del category_ids[0:ones_last_index]
for i in range(a.count(' ')):
a.remove(' ')
Đơn giản hơn nhiều tôi tin.
Để cho
>>> x = [1, 2, 3, 4, 2, 2, 3]
Giải pháp đơn giản và hiệu quả nhất như đã đăng trước đó là
>>> x[:] = [v for v in x if v != 2]
>>> x
[1, 3, 4, 3]
Một khả năng khác nên sử dụng ít bộ nhớ hơn nhưng chậm hơn là
>>> for i in range(len(x) - 1, -1, -1):
if x[i] == 2:
x.pop(i) # takes time ~ len(x) - i
>>> x
[1, 3, 4, 3]
Kết quả thời gian cho danh sách có độ dài 1000 và 100000 với 10% mục khớp: 0,16 so với 0,25 ms và 23 so với 123 ms.
lists = [6.9,7,8.9,3,5,4.9,1,2.9,7,9,12.9,10.9,11,7]
def remove_values_from_list():
for list in lists:
if(list!=7):
print(list)
remove_values_from_list()
Kết quả: 6.9 8.9 3 5 4.9 1 2.9 9 12.9 10.9 11
lists = [6.9,7,8.9,3,5,4.9,1,2.9,7,9,12.9,10.9,11,7]
def remove_values_from_list(remove):
for list in lists:
if(list!=remove):
print(list)
remove_values_from_list(7)
Kết quả: 6.9 8.9 3 5 4.9 1 2.9 9 12.9 10.9 11
hello = ['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd']
#chech every item for a match
for item in range(len(hello)-1):
if hello[item] == ' ':
#if there is a match, rebuild the list with the list before the item + the list after the item
hello = hello[:item] + hello [item + 1:]
print hello
['Chào thế giới']
Tôi chỉ làm điều này cho một danh sách. Tôi chỉ là người mới bắt đầu. Một lập trình viên cao cấp hơn một chút chắc chắn có thể viết một hàm như thế này.
for i in range(len(spam)):
spam.remove('cat')
if 'cat' not in spam:
print('All instances of ' + 'cat ' + 'have been removed')
break
Chúng tôi cũng có thể xóa tại chỗ bằng cách sử dụng một trong hai del
hoặc pop
:
import random
def remove_values_from_list(lst, target):
if type(lst) != list:
return lst
i = 0
while i < len(lst):
if lst[i] == target:
lst.pop(i) # length decreased by 1 already
else:
i += 1
return lst
remove_values_from_list(None, 2)
remove_values_from_list([], 2)
remove_values_from_list([1, 2, 3, 4, 2, 2, 3], 2)
lst = remove_values_from_list([random.randrange(0, 10) for x in range(1000000)], 2)
print(len(lst))
Bây giờ cho hiệu quả:
In [21]: %timeit -n1 -r1 x = random.randrange(0,10)
1 loop, best of 1: 43.5 us per loop
In [22]: %timeit -n1 -r1 lst = [random.randrange(0, 10) for x in range(1000000)]
g1 loop, best of 1: 660 ms per loop
In [23]: %timeit -n1 -r1 lst = remove_values_from_list([random.randrange(0, 10) for x in range(1000000)]
...: , random.randrange(0,10))
1 loop, best of 1: 11.5 s per loop
In [27]: %timeit -n1 -r1 x = random.randrange(0,10); lst = [a for a in [random.randrange(0, 10) for x in
...: range(1000000)] if x != a]
1 loop, best of 1: 710 ms per loop
Như chúng ta thấy phiên bản tại chỗ remove_values_from_list()
không cần thêm bộ nhớ, nhưng sẽ mất nhiều thời gian hơn để chạy:
Không ai đã đăng một câu trả lời tối ưu cho sự phức tạp về thời gian và không gian, vì vậy tôi nghĩ rằng tôi sẽ cho nó một shot. Dưới đây là một giải pháp loại bỏ tất cả các lần xuất hiện của một giá trị cụ thể mà không tạo ra một mảng mới và ở độ phức tạp thời gian hiệu quả. Hạn chế là các yếu tố không duy trì trật tự .
Độ phức tạp thời gian: O (n)
Độ phức tạp không gian bổ sung: O (1)
def main():
test_case([1, 2, 3, 4, 2, 2, 3], 2) # [1, 3, 3, 4]
test_case([3, 3, 3], 3) # []
test_case([1, 1, 1], 3) # [1, 1, 1]
def test_case(test_val, remove_val):
remove_element_in_place(test_val, remove_val)
print(test_val)
def remove_element_in_place(my_list, remove_value):
length_my_list = len(my_list)
swap_idx = length_my_list - 1
for idx in range(length_my_list - 1, -1, -1):
if my_list[idx] == remove_value:
my_list[idx], my_list[swap_idx] = my_list[swap_idx], my_list[idx]
swap_idx -= 1
for pop_idx in range(length_my_list - swap_idx - 1):
my_list.pop() # O(1) operation
if __name__ == '__main__':
main()
Về tốc độ!
import time
s_time = time.time()
print 'start'
a = range(100000000)
del a[:]
print 'finished in %0.2f' % (time.time() - s_time)
# start
# finished in 3.25
s_time = time.time()
print 'start'
a = range(100000000)
a = []
print 'finished in %0.2f' % (time.time() - s_time)
# start
# finished in 2.11
Có chuyện gì với:
Motor=['1','2','2']
For i in Motor:
If i != '2':
Print(i)
Print(motor)
Sử dụng anaconda