Sekarang saya tahu bahwa tidak aman untuk mengubah daftar selama perulangan berulang. Namun, anggaplah saya memiliki daftar string, dan saya ingin menghapus string sendiri. Apakah penggantian nilai yang dapat diubah dianggap sebagai modifikasi?
Sekarang saya tahu bahwa tidak aman untuk mengubah daftar selama perulangan berulang. Namun, anggaplah saya memiliki daftar string, dan saya ingin menghapus string sendiri. Apakah penggantian nilai yang dapat diubah dianggap sebagai modifikasi?
Jawaban:
Itu dianggap bentuk yang buruk. Gunakan pemahaman daftar sebagai gantinya, dengan tugas irisan jika Anda perlu mempertahankan referensi yang ada ke daftar.
a = [1, 3, 5]
b = a
a[:] = [x + 2 for x in a]
print(b)
print bpernyataan dijalankan, Anda dapat mengetahui apakah atelah dimodifikasi di tempat daripada diganti. Kemungkinan lain adalah print b is amelihat apakah keduanya masih merujuk pada objek yang sama.
Karena loop di bawah ini hanya memodifikasi elemen yang sudah dilihat, itu akan dianggap dapat diterima:
a = ['a',' b', 'c ', ' d ']
for i, s in enumerate(a):
a[i] = s.strip()
print(a) # -> ['a', 'b', 'c', 'd']
Yang berbeda dari:
a[:] = [s.strip() for s in a]
dalam hal itu tidak memerlukan pembuatan daftar sementara dan penugasan untuk menggantikan yang asli, meskipun itu membutuhkan lebih banyak operasi pengindeksan.
Perhatian: Meskipun Anda dapat memodifikasi entri dengan cara ini, Anda tidak dapat mengubah jumlah item listtanpa mempertaruhkan peluang menghadapi masalah.
Inilah contoh yang saya maksud — menghapus entri mengacaukan pengindeksan sejak saat itu:
b = ['a', ' b', 'c ', ' d ']
for i, s in enumerate(b):
if s.strip() != b[i]: # leading or trailing whitespace?
del b[i]
print(b) # -> ['a', 'c '] # WRONG!
(Hasilnya salah karena tidak menghapus semua item yang seharusnya.)
Memperbarui
Karena ini adalah jawaban yang cukup populer, berikut ini cara menghapus entri "di tempat" secara efektif (meskipun itu bukan pertanyaan):
b = ['a',' b', 'c ', ' d ']
b[:] = [entry for entry in b if entry.strip() == entry]
print(b) # -> ['a'] # CORRECT
for i in a? Ini sangat berlawanan dengan intuisi, tampaknya berbeda dari bahasa lain dan telah mengakibatkan kesalahan pada kode saya sehingga saya harus melakukan debug untuk jangka waktu yang lama. Tutorial Python bahkan tidak menyebutkannya. Meskipun harus ada alasan untuk itu?
a[i]dan s) untuk objek yang sama di baris yang sama ketika Anda tidak perlu? Saya lebih suka melakukannya a[i] = a[i].strip().
a[i] = s.strip()hanya satu operasi pengindeksan.
enumerate(b)melakukan operasi pengindeksan pada setiap iterasi dan Anda melakukannya dengan yang lain a[i] =. AFAIK tidak mungkin untuk mengimplementasikan loop ini dalam Python dengan hanya 1 operasi pengindeksan per loop iterasi :(
Satu lagi untuk varian loop, terlihat lebih bersih bagi saya daripada satu dengan enumerate ():
for idx in range(len(list)):
list[idx]=... # set a new value
# some other code which doesn't let you use a list comprehension
range(len(list))di Python sebagai bau kode.
enumerategenerator itu tidak membuat daftar. Dari tupel, itu membuat mereka satu per satu saat iterates melalui daftar. Satu-satunya cara untuk mengetahui mana yang lebih lambat adalah dengan timeit.
Memodifikasi setiap elemen saat iterasi daftar baik-baik saja, selama Anda tidak mengubah menambah / menghapus elemen ke daftar.
Anda dapat menggunakan pemahaman daftar:
l = ['a', ' list', 'of ', ' string ']
l = [item.strip() for item in l]
atau lakukan saja C-stylefor loop:
for index, item in enumerate(l):
l[index] = item.strip()
Tidak, Anda tidak akan mengubah "konten" daftar, jika Anda dapat mengubah string dengan cara itu. Tetapi dalam Python mereka tidak bisa berubah. Operasi string apa pun mengembalikan string baru.
Jika Anda memiliki daftar objek yang Anda tahu bisa berubah, Anda bisa melakukan ini selama Anda tidak mengubah konten sebenarnya dari daftar.
Dengan demikian Anda perlu melakukan semacam peta. Jika Anda menggunakan ekspresi generator itu [operasi] akan dilakukan saat Anda mengulanginya dan Anda akan menghemat memori.
Jawaban yang diberikan oleh Jemshit Iskenderov dan Ignacio Vazquez-Abrams sangat bagus. Lebih lanjut dapat diilustrasikan dengan contoh ini: bayangkan itu
a) Daftar dengan dua vektor diberikan kepada Anda;
b) Anda ingin melintasi daftar dan membalikkan urutan masing-masing array
Katakanlah Anda punya
v = np.array([1, 2,3,4])
b = np.array([3,4,6])
for i in [v, b]:
i = i[::-1] # this command does not reverse the string
print([v,b])
Kamu akan mendapatkan
[array([1, 2, 3, 4]), array([3, 4, 6])]
Di sisi lain, jika Anda melakukannya
v = np.array([1, 2,3,4])
b = np.array([3,4,6])
for i in [v, b]:
i[:] = i[::-1] # this command reverses the string
print([v,b])
Hasilnya adalah
[array([4, 3, 2, 1]), array([6, 4, 3])]
Tidak jelas dari pertanyaan Anda apa kriteria untuk memutuskan string apa yang harus dihapus, tetapi jika Anda memiliki atau dapat membuat daftar string yang ingin Anda hapus, Anda dapat melakukan hal berikut:
my_strings = ['a','b','c','d','e']
undesirable_strings = ['b','d']
for undesirable_string in undesirable_strings:
for i in range(my_strings.count(undesirable_string)):
my_strings.remove(undesirable_string)
yang mengubah my_strings menjadi ['a', 'c', 'e']
Singkatnya, untuk melakukan modifikasi pada daftar sambil mengulangi daftar yang sama.
list[:] = ["Modify the list" for each_element in list "Condition Check"]
contoh:
list[:] = [list.remove(each_element) for each_element in list if each_element in ["data1", "data2"]]