නැවත සැකසීමේදී ලැයිස්තුවකින් අයිතම ඉවත් කරන්නේ කෙසේද?


934

මම පයිතන්හි ටුපල් ලැයිස්තුවක් හරහා නැවත කියමි, ඒවා යම් නිර්ණායක සපුරාලන්නේ නම් ඒවා ඉවත් කිරීමට උත්සාහ කරමි.

for tup in somelist:
    if determine(tup):
         code_to_remove_tup

ඒ වෙනුවට මා භාවිතා කළ යුත්තේ code_to_remove_tupකුමක්ද? මෙම විලාසිතාවේ ඇති අයිතමය ඉවත් කරන්නේ කෙසේදැයි මට සිතාගත නොහැක.


මෙම පිටුවේ ඇති බොහෝ පිළිතුරු ලැයිස්තුවක් නැවත සැකසීමේදී මූලද්‍රව්‍ය ඉවත් කිරීම අමුතු ප්‍රති results ල ලබා දෙන්නේ මන්දැයි පැහැදිලි නොකරයි, නමුත් මෙම ප්‍රශ්නයේ පිළිගත් පිළිතුර එය ලබා දෙන අතර පළමු වරට මෙම ගැටලුවට මුහුණ දෙන ආරම්භකයින් සඳහා වඩා හොඳ ඩුප් එකක් විය හැකිය.
ggorlen

Answers:


860

ඔබට ඉවත් කිරීමට අවශ්‍ය නොවන අංග පමණක් අඩංගු නව ලැයිස්තුවක් සෑදීමට ඔබට ලැයිස්තු අවබෝධය භාවිතා කළ හැකිය:

somelist = [x for x in somelist if not determine(x)]

නැතහොත්, පෙත්තට පැවරීමෙන් somelist[:], ඔබට අවශ්‍ය අයිතම පමණක් අඩංගු වන පරිදි පවතින ලැයිස්තුව විකෘති කළ හැකිය:

somelist[:] = [x for x in somelist if not determine(x)]

somelistවෙනස්කම් පිළිබිඹු කිරීම සඳහා වෙනත් යොමු කිරීම් තිබේ නම් මෙම ප්‍රවේශය ප්‍රයෝජනවත් වේ .

අවබෝධයක් වෙනුවට, ඔබට ද භාවිතා කළ හැකිය itertools. පයිතන් 2 හි:

from itertools import ifilterfalse
somelist[:] = ifilterfalse(determine, somelist)

හෝ පයිතන් 3 හි:

from itertools import filterfalse
somelist[:] = filterfalse(determine, somelist)

පැහැදිලිකම සහ [:]අංකනය අනවසරයෙන් හෝ නොපැහැදිලි ලෙස භාවිතා කරන අය සඳහා , මෙන්න වඩාත් පැහැදිලි විකල්පයක්. න්‍යායාත්මකව, එය ඉහත එක් ලයිනර් වලට වඩා අවකාශය හා වේලාව සම්බන්ධයෙන් සමාන ලෙස ක්‍රියා කළ යුතුය.

temp = []
while somelist:
    x = somelist.pop()
    if not determine(x):
        temp.append(x)
while temp:
    somelist.append(templist.pop())

අවම වෙනස් කිරීම් සහිතව, පයිතන් ලැයිස්තු වෙනුවට ආදේශ කිරීමේ අයිතම නොමැති වෙනත් භාෂාවලින්ද එය ක්‍රියා කරයි . නිදසුනක් ලෙස, Falseපයිතන් මෙන් සෑම භාෂාවක්ම හිස් ලැයිස්තු a ට දමන්නේ නැත. ඔබට while somelist:වඩා පැහැදිලි යමක් වෙනුවට ආදේශ කළ හැකිය while len(somelist) > 0:.


4
ස්වල්පයක් පමණක් මකා දැමෙනු ඇතැයි ඔබ දන්නේ නම් ඔබට එය වේගවත් කළ හැකිද, එනම් ඒවා මකා දමා අනෙක් ඒවා නැවත ලිවීමට වඩා තැනින් තැන තබන්න.
highBandWidth

25
මගේ ලැයිස්තුව විශාල නම් සහ පිටපතක් සෑදිය නොහැකි නම් කුමක් කළ යුතුද?
jpcgt

17
pjpcgt ඔබ somelist[:] = (x for x in somelist if determine(x))මෙය භාවිතා කළ යුත්තේ අනවශ්‍ය පිටපත් නිර්මාණය නොකරන ජනක යන්ත්‍රයක් නිර්මාණය කරමිනි.
රොස්ටිස්ලාව් කොන්ඩ්‍රැටෙන්කෝ

8
OstRostislavKondratenko: අභ්‍යන්තරව ඇමතුම් list_ass_slice()ක්‍රියාත්මක කරන ශ්‍රිතය . මෙම ශ්‍රිතය සැමවිටම ලැයිස්තුවක් ලබා දෙයි, එනම්, ජනක යන්ත්‍රයක් වෙනුවට දැනටමත් ලැයිස්තුවක් භාවිතා කරන ඇලෙක්ස් මාටෙලිගේ විසඳුම වඩාත් කාර්යක්ෂම වේsomelist[:]=PySequence_Fast()
jfs

6
කරුණාකර ලැයිස්තු අවබෝධය ලැයිස්තුවට පැවරීම සහ ලැයිස්තු ක්ලෝන අතර ඇති වෙනස්කම් මොනවාදැයි පැහැදිලි කිරීමට ඔබ කැමතිද? මුල් ලැයිස්තුව somelistක්‍රම දෙකෙන්ම විකෘති නොවන්නේද?
බොවන් ලියු

596

ලැයිස්තු අවබෝධය යෝජනා කරන පිළිතුරු බොහෝ දුරට නිවැරදි ය - ඒවා සම්පූර්ණයෙන්ම නව ලැයිස්තුවක් ගොඩනඟා පැරණි ලැයිස්තුවට සමාන නමක් ලබා දීම හැර, ඔවුන් පැරණි ලැයිස්තුව වෙනස් නොකරයි. @ ලෙනාට්ගේ යෝජනාවට අනුව, තෝරා බේරා ඉවත් කිරීමෙන් ඔබ කරන දෙයට වඩා එය වෙනස් ය - එය වේගවත් ය, නමුත් ඔබේ ලැයිස්තුව බහුවිධ යොමු කිරීම් හරහා ප්‍රවේශ වන්නේ නම්, ඔබ එක් යොමුවකට සමාන වන අතර ලැයිස්තු වස්තුව වෙනස් නොකරයි සියුම්, විනාශකාරී දෝෂ වලට තුඩු දිය හැකිය.

වාසනාවකට මෙන්, ලැයිස්තු අවබෝධයේ වේගය සහ ස්ථානීය වෙනස් කිරීම සඳහා අවශ්‍ය අර්ථ නිරූපණය යන දෙකම ලබා ගැනීම අතිශයින්ම පහසුය - හුදෙක් කේතය:

somelist[:] = [tup for tup in somelist if determine(tup)]

වෙනත් පිළිතුරු සමඟ සියුම් වෙනසක් සටහන: මෙම එක් barename පවරා, දෙයක් නොවේ - එය හුදෙක් මුළු ලැයිස්තුවක් විය කිරීමට සිදු වන ලැයිස්තුවක් පෙත්තක් පවරා, වෙනවා, එමගින් ලැයිස්තුව වෙනුවට අන්තර්ගතයන් එම පිඹුරා ලැයිස්තුව වස්තුව තුළ නොව එක් සඳහනක් reseating වඩා, (පෙර ලැයිස්තු වස්තුවේ සිට නව ලැයිස්තු වස්තුව දක්වා) අනෙක් පිළිතුරු මෙන්.


1
පෙති කපන ලද පැවරුම ආ ict ාවක් සමඟ කරන්නේ කෙසේද? පයිතන් 2.6 හි?
පෝල්එම්සීජී

11
A පෝල්: ඩික්ස් අනුපිළිවෙලට නොමැති බැවින් පෙති ඩික් සඳහා අර්ථ විරහිත ය. Dict අන්තර්ගතය වෙනුවට ඔබේ අවශ්ය නම් adict අන්තර්ගතය විසින් b, භාවිතා a.clear(); a.update(b).
ස්වෙන් මාර්නාච්

1
දෝෂ ඇතිවීමට විචල්‍යය යොමු කරන දේ ප්‍රතිස්ථාපනය කිරීමෙන් එක් යොමු කිරීමක් 'නැවත' කළ හැක්කේ ඇයි? එය තනි නූල් නොව බහු-නූල් යෙදුම්වල විභව ගැටලුවක් පමණක් බව පෙනේ.
ඩෙරෙක් ඩැමර්

64
E ඩෙරෙක් x = ['foo','bar','baz']; y = x; x = [item for item in x if determine(item)];මෙය xලැයිස්තු අවබෝධයේ ප්‍රති result ලයට නැවත පැවරේ , නමුත් yතවමත් මුල් ලැයිස්තුවට යොමු ['foo','bar','baz']වේ. ඔබ අපේක්ෂා කළේ නම් xසහ yඑකම ලැයිස්තුවට යොමු වීමට නම්, ඔබ දෝෂ හඳුන්වා දී ඇත. ඇලෙක්ස් පෙන්වන පරිදි, සමස්ත ලැයිස්තුවේ පෙත්තකට පැවරීමෙන් ඔබ මෙය වළක්වයි, මම මෙහි පෙන්වන්නේ : x = ["foo","bar","baz"]; y = x; x[:] = [item for item in x if determine(item)];. ලැයිස්තුව වෙනස් කර ඇත. ලැයිස්තුවේ සියලුම යොමු කිරීම් (දෙකම xසහ yමෙහි) නව ලැයිස්තුවට යොමු වන බව සහතික කිරීම .
ස්ටීවන් ටී. ස්නයිඩර්

ඇත්ත වශයෙන්ම, filterශ්‍රිතය භාවිතා කිරීම ද නව ලැයිස්තුවක් සාදයි, තැනින් තැන අංග වෙනස් නොකරයි ... පමණිolist[:] = [i for i in olist if not dislike(i)]
ජෝන් ස්ට්‍රූඩ්

310

ඔබ ලැයිස්තුවේ පිටපතක් ගෙන එය මුලින් නැවත කියවිය යුතුය, නැතහොත් අනපේක්ෂිත ප්‍රති .ල සමඟ නැවත ක්‍රියා කිරීම අසාර්ථක වනු ඇත.

උදාහරණයක් ලෙස (කුමන ආකාරයේ ලැයිස්තුවක් මත රඳා පවතී):

for tup in somelist[:]:
    etc....

උදාහරණයක්:

>>> somelist = range(10)
>>> for x in somelist:
...     somelist.remove(x)
>>> somelist
[1, 3, 5, 7, 9]

>>> somelist = range(10)
>>> for x in somelist[:]:
...     somelist.remove(x)
>>> somelist
[]

13
En සෙන් ලැයිස්තුවේ පිටපතක් දෙවැන්න නැවත කියවන බැවිනි. එබැවින් ඔබ මුල් ලැයිස්තුව වෙනස් කරන විට, ඔබ නැවත කියවන පිටපත වෙනස් නොකරයි.
ලෙනාට් රෙජෙබ්‍රෝ

3
ලැයිස්තුවට (සමලිස්ට්) හා සසඳන විට [:] සමලිස්ට් කිරීම වඩා හොඳ කුමක්ද?
මාරියස් ජම්රෝ

3
list(somelist)නැවත සැකසිය හැකි ලැයිස්තුවක් බවට පරිවර්තනය කරයි. somelist[:]පෙති කැපීමට සහාය වන වස්තුවක පිටපතක් සාදයි. ඒ නිසා ඔවුන් අනිවාර්යයෙන්ම එකම දේ කරන්නේ නැහැ. මෙම අවස්ථාවේදී මට somelistවස්තුවේ පිටපතක් සෑදීමට අවශ්‍යයි , එබැවින් මම භාවිතා කරමි[:]
ලෙනාට් රීජෙබ්‍රෝ

36
මෙය කියවන ඕනෑම කෙනෙකුට සටහන් කරන්න, මෙය ලැයිස්තු සඳහා ඉතා මන්දගාමී වේ. remove()සෑම ක්‍රියාවලියක් සඳහාම WHOLE ලැයිස්තුවට ඉහළින් යා යුතුය, එබැවින් එය සදහටම ගත වේ.
vitiral

8
අයිතම දුසිමක් පමණක් ලැයිස්තු ගත කිරීමේදී බිග් ඕ වේලාව වැදගත් නොවේ. අනාගත ක්‍රමලේඛකයින්ට තේරුම් ගැනීමට බොහෝ විට පැහැදිලි හා සරල කාර්ය සාධනයට වඩා වටිනවා.
ස්ටීව්

132
for i in range(len(somelist) - 1, -1, -1):
    if some_condition(somelist, i):
        del somelist[i]

ඔබ පසුපසට යා යුතුය, එසේ නොමැතිනම් එය ඔබ වාඩි වී සිටින ගස් අත්ත කපා දැමීම වැනි ය :-)

Python මීට උදාහරණ 2 පරිශීලකයින්: වෙනුවට rangeවිසින් xrangeඑය hardcoded ලැයිස්තුව නිර්මාණය වළක්වා ගැනීමට


13
Python මෑතකදී නිකුත් වූ සංස්කරණයන් හි, ඔබ භාවිතා කරමින් වඩාත් පැහැදිලිව මෙය කළ හැකි reversed()builtin
ncoghlan

17
ප්‍රතිවර්තනය () නව ලැයිස්තුවක් සාදන්නේ නැත, එය සැපයූ අනුක්‍රමයට වඩා ප්‍රතිලෝම අනුකාරකයක් සාදයි. ගණනය කිරීම () මෙන්, ඇත්ත වශයෙන්ම එයින් ලැයිස්තුවක් ලබා ගැනීම සඳහා ඔබ එය ලැයිස්තුවේ () ඔතා තැබිය යුතුය. ඔබ කරන, හිඳගෙන, සිතීමෙන්, කළ හැකිය () කරන්නේ (එය නිරාකරණය කළ හැකි නිසා එය වෙත ඇති) සෑම අවස්ථාවකදීම අලුත් ලැයිස්තුවක් නිර්මාණය.
ncoghlan

1
A මෞරිස් නිසා එය enumerateනැවත ලබා දෙන reversedඅනුපිළිවෙලක් බලාපොරොත්තු වේ. reversed(list(enumerate(somelist)))මතකයේ අතිරේක ලැයිස්තුවක් සෑදීමට ඔබට අවශ්‍ය නැතිනම් ඔබට එය කළ හැකි යැයි මම සිතමි .
ඩ්‍රෙවිකෝ

2
අරා සඳහා මෙය O (N * M) වේ, ඔබ විශාල ලැයිස්තුවකින් බොහෝ අයිතම ඉවත් කළහොත් එය ඉතා මන්දගාමී වේ. එබැවින් නිර්දේශ නොකරයි.
සෑම් වොට්කින්ස්

2
AmSamWatkins ඔව්, මෙම පිළිතුර ඔබ ඉතා විශාල පෙළකින් මූලද්‍රව්‍ය කිහිපයක් ඉවත් කරන විට ය. මතක භාවිතය අඩු නමුත් එය mකිහිප වතාවක් මන්දගාමී විය හැකිය .
නවීන්

56

හොඳම ක්‍රියාමාර්ග

එක්කෝ:

  • සම්බන්ධිත ලැයිස්තු ක්‍රියාත්මක කිරීමක් භාවිතා කරන්න / ඔබේම දෑ රෝල් කරන්න.

    සම්බන්ධිත ලැයිස්තුවක් යනු ගැටළුව සඳහා නිසි දත්ත ව්‍යුහයක් වන අතර අවකාශය / වේලාව වෙළඳාම් කිරීමට ඔබට බල නොකරයි.

    කෙසේ වෙතත් සම්මත පුස්තකාලයේ එකක් ඇති බවක් නොපෙනේ:

  • මුල සිටම නව list()එකක් ආරම්භ කරන්න, .append()අවසානයේ සඳහන් කළ පරිදි ආපසු: https://stackoverflow.com/a/1207460/895245

    මෙම කාලය කාර්යක්ෂම, නමුත් අඩු ඉඩ කාර්යක්ෂමතාවයක් ඇති බැවින් එය පුනරාවර්තනයේදී අරාවෙහි පිටපතක් තබා ගනී.

  • මෙහි delසඳහන් පරිදි දර්ශකයක් සමඟ භාවිතා කරන්න: https://stackoverflow.com/a/1207485/895245

    අරාව පිටපත බෙදා හරින බැවින් මෙය වඩා අභ්‍යවකාශ කාර්යක්ෂම වේ, නමුත් එය අඩු කාලයක් කාර්යක්ෂම වන්නේ CPython ලැයිස්තු ගතික අරා සමඟ ක්‍රියාත්මක වන බැවිනි .

    මෙයින් අදහස් කරන්නේ අයිතමය ඉවත් කිරීම සඳහා පහත සඳහන් සියලුම අයිතම එකින් එක මාරු කිරීම අවශ්‍ය වන අතර එය O (N) වේ.

සාමාන්‍යයෙන්, ඔබ එය ඉක්මන් හා අපිරිසිදු කරන්නේ නම් සහ අභිරුචි LinkedListපන්තියක් එක් කිරීමට අවශ්‍ය නොවන්නේ නම් , ඔබට අවශ්‍ය වන්නේ .append()මතකය විශාල අවධානයක් යොමු නොකරන්නේ නම් පෙරනිමියෙන් වේගවත් විකල්පය සඳහා ය .

නිල පයිතන් 2 නිබන්ධනය 4.2. "ප්‍රකාශන සඳහා"

https://docs.python.org/2/tutorial/controlflow.html#for-statements

ලේඛනයේ මෙම කොටස එය පැහැදිලි කරයි:

  • එය වෙනස් කිරීම සඳහා නැවත සැකසූ ලැයිස්තුවේ පිටපතක් සෑදිය යුතුය
  • එය කළ හැකි එක් ක්‍රමයක් වන්නේ පෙති අංකනයයි [:]

ලූපය තුළ සිටියදී ඔබ නැවත නැවතත් කරන අනුක්‍රමය වෙනස් කිරීමට ඔබට අවශ්‍ය නම් (නිදසුනක් ලෙස තෝරාගත් අයිතම අනුපිටපත් කිරීම සඳහා), ඔබ මුලින්ම පිටපතක් සෑදීම රෙකමදාරු කරනු ලැබේ. අනුක්‍රමයක් හරහා අනුකරණය කිරීම ව්‍යංගයෙන් පිටපතක් නොකරයි. පෙති අංකනය මෙය විශේෂයෙන් පහසු කරයි:

>>> words = ['cat', 'window', 'defenestrate']
>>> for w in words[:]:  # Loop over a slice copy of the entire list.
...     if len(w) > 6:
...         words.insert(0, w)
...
>>> words
['defenestrate', 'cat', 'window', 'defenestrate']

පයිතන් 2 ප්‍රලේඛනය 7.3. "ප්‍රකාශය සඳහා"

https://docs.python.org/2/reference/compound_stmts.html#for

ලේඛනයේ මෙම කොටස නැවත වරක් ඔබ පිටපතක් සෑදිය යුතු බව පවසන අතර සත්‍ය ඉවත් කිරීමේ උදාහරණයක් සපයයි:

සටහන: ලූපය මගින් අනුක්‍රමය වෙනස් කරන විට සියුම් බවක් ඇත (මෙය සිදුවිය හැක්කේ විකෘති අනුක්‍රම සඳහා පමණි, එනම් ලැයිස්තු). ඊළඟට භාවිතා කරන්නේ කුමන අයිතමයද යන්න නිරීක්ෂණය කිරීම සඳහා අභ්‍යන්තර කවුන්ටරයක් ​​භාවිතා කරන අතර, එක් එක් පුනරාවර්තනය මත මෙය වැඩි වේ. මෙම කවුන්ටරය අනුක්‍රමයේ දිගට ළඟා වූ විට ලූපය අවසන් වේ. මෙයින් අදහස් කරන්නේ කට්ටලය වත්මන් (හෝ පෙර) අයිතමය අනුක්‍රමයෙන් මකා දැමුවහොත්, ඊළඟ අයිතමය මඟ හරිනු ඇති බවයි (එයට දැනටමත් ප්‍රතිකාර කර ඇති වත්මන් අයිතමයේ දර්ශකය ලැබෙන බැවින්). ඒ හා සමානව, කට්ටලය වත්මන් අයිතමයට පෙර අනුපිළිවෙලට අයිතමයක් ඇතුළත් කළහොත්, වත්මන් අයිතමය ඊළඟ වතාවේ ලූපය හරහා නැවත සලකනු ලැබේ. මෙය සමස්ත අනුක්‍රමයේ පෙත්තක් භාවිතා කර තාවකාලික පිටපතක් සෑදීමෙන් වළක්වා ගත හැකි නපුරු දෝෂ වලට හේතු විය හැක, උදා.

for x in a[:]:
    if x < 0: a.remove(x)

කෙසේ වෙතත්, මෙම ක්‍රියාවට නැංවීමට මම එකඟ නොවෙමි, මන්ද එහි වටිනාකම සොයා ගැනීම සඳහා සමස්ත ලැයිස්තුවම නැවත .remove()සැකසිය යුතුය.

පයිතන්ට මෙය වඩා හොඳින් කළ හැකිද?

මෙම විශේෂිත පයිතන් API වැඩි දියුණු කළ හැකි බව පෙනේ. උදාහරණයක් ලෙස, මෙය සසඳා බලන්න:

  • Java ListIterator :: කුමන ලියකියවිලි ඉවත් කරන්න "මෙම ඇමතුම කළ හැක්කේ ඊළඟ හෝ ඊට පෙර ඇමතුමකට එක් වරක් පමණි"
  • C ++ std::vector::eraseඉවත් කළ පසු මූලද්‍රව්‍යයට වලංගු අන්තර්ක්‍රියාකාරකයක් ලබා දෙයි

මේ දෙකම ඔබට පැහැදිලිවම කියැවෙන්නේ ඔබට නැවත සැකසෙන ලැයිස්තුවක් වෙනස් කළ නොහැකි බව ය.

සමහර විට යටින් පවතින තාර්කිකත්වය නම්, පයිතන් ලැයිස්තු ගතික අරා පිටුබලය ඇති බවට උපකල්පනය කර ඇති අතර, එබැවින් ඕනෑම ආකාරයක ඉවත් කිරීමක් කෙසේ හෝ කාලය අකාර්යක්ෂම වනු ඇති අතර, ජාවා දෙකම ArrayListහා LinkedListක්‍රියාත්මක කිරීම සමඟ වඩා හොඳ අතුරු මුහුණත් ධූරාවලියක් ඇත ListIterator.

පයිතන් ස්ටඩ්ලිබ් හි පැහැදිලි සම්බන්ධිත ලැයිස්තු වර්ගයක් ඇති බවක් නොපෙනේ: පයිතන් සම්බන්ධිත ලැයිස්තුව


48

එවැනි උදාහරණයක් සඳහා ඔබේ හොඳම ප්‍රවේශය ලැයිස්තු අවබෝධයක් වනු ඇත

somelist = [tup for tup in somelist if determine(tup)]

ඔබ determineශ්‍රිතයක් ඇමතීමට වඩා සංකීර්ණ දෙයක් කරන අවස්ථාවන්හිදී, මම කැමති නව ලැයිස්තුවක් තැනීමට සහ මා යන විට එයට එකතු වීමටයි. උදාහරණයක් වශයෙන්

newlist = []
for tup in somelist:
    # lots of code here, possibly setting things up for calling determine
    if determine(tup):
        newlist.append(tup)
somelist = newlist

removeපහත දැක්වෙන පිළිතුරකින් විස්තර කර ඇති පරිදි, ලැයිස්තුව පිටපත් කිරීමෙන් ඔබේ කේතය ටිකක් පිරිසිදු විය හැකිය. අතිශයින්ම විශාල ලැයිස්තු සඳහා ඔබ මෙය අනිවාර්යයෙන්ම නොකළ යුතුය, මන්දයත් මුලින්ම මුළු ලැයිස්තුවම පිටපත් කිරීමත්, O(n) removeඑක් එක් මූලද්‍රව්‍යය ඉවත් කිරීම සඳහා මෙහෙයුමක් සිදු කිරීමත් නිසා මෙය O(n^2)ඇල්ගොරිතමයක් බවට පත් වේ.

for tup in somelist[:]:
    # lots of code here, possibly setting things up for calling determine
    if determine(tup):
        newlist.append(tup)

37

ක්‍රියාකාරී වැඩසටහන් වලට කැමති අය සඳහා:

somelist[:] = filter(lambda tup: not determine(tup), somelist)

හෝ

from itertools import ifilterfalse
somelist[:] = list(ifilterfalse(determine, somelist))

1. ලැයිස්තු අවබෝධය සහ උත්පාදක ප්‍රකාශන පිරිසිදු ක්‍රියාකාරී භාෂාවක් වන හස්කල් වෙතින් ලබා ගනී; ඒවා හරියටම ක්‍රියාකාරී filterවන අතර වඩා පයිතොනික් වේ. 2. ඔබට lambdaභාවිතා කිරීමට අවශ්‍ය නම් mapහෝ filter, ලැයිස්තු සංයුක්ත හෝ ජෙනෙක්ස්ප්‍රස් සෑම විටම වඩා හොඳ විකල්පය වේ; mapහා filterපරිවර්තනය / සංජානන කාර්යය වන්නේ පයිතන් යනු බිල්ට් විට දී සී ක්රියාත්මක වන අතර iterable trivially සුළු පටු නොවේ, නමුත් ඔවුන් සෑම විටම මන්දගාමී ඔබට අවශ්ය විට ඉන්නේ තරමක් වේගයෙන් විය හැකි lambdaද listcomp / genexpr වළක්වා හැකි බව.
ෂැඩෝ රේන්ජර්

14

මට මෙය විශාල ලැයිස්තුවක් සමඟ කිරීමට අවශ්‍ය වූ අතර, ලැයිස්තුව අනුපිටපත් කිරීම මිල අධික බවක් පෙනෙන්නට තිබුණි, විශේෂයෙන් ම, ඉතිරිව ඇති අයිතම සමඟ සසඳන විට මකාදැමීම් ගණන ස්වල්පයක් වනු ඇත. මම මේ පහත් මට්ටමේ ප්‍රවේශය ගත්තා.

array = [lots of stuff]
arraySize = len(array)
i = 0
while i < arraySize:
    if someTest(array[i]):
        del array[i]
        arraySize -= 1
    else:
        i += 1

මා නොදන්නා දෙය නම් විශාල ලැයිස්තුවක් පිටපත් කිරීමට සාපේක්ෂව මකාදැමීම් කිහිපයක් කොතරම් කාර්යක්ෂමද යන්නයි. ඔබට යම් අවබෝධයක් ඇත්නම් කරුණාකර අදහස් දක්වන්න.


මගේ නඩුවේදී මට එම 'අනවශ්‍ය' අංග වෙනත් ලැයිස්තුවකට ගෙන යා යුතුය. මෙම විසඳුම පිළිබඳව ඔබට නව අදහසක් තිබේද? ලැයිස්තුව අනුපිටපත් කිරීම වෙනුවට සමහර මකාදැමීම් භාවිතා කිරීම වඩා හොඳ යැයි මම සිතමි.
gustavovelascoh

කාර්ය සාධනය ගැටළුවක් නම් මෙය නිවැරදි පිළිතුරයි (lex ඇලෙක්සි හා සමාන වුවත්). listලැයිස්තුවේ මැද සිට ඉවත් කිරීම ලැයිස්තුවේ දිගට රේඛීය කාලයක් ගත වන බැවින්, මුලින් දත්ත ව්‍යුහයක් ලෙස තෝරා ගැනීම ප්‍රවේශමෙන් සලකා බැලිය යුතුය. ඔබට k-th අනුක්‍රමික අයිතමයට අහඹු ලෙස ප්‍රවේශය අවශ්‍ය නොවේ නම්, සමහර විට සලකා බලන්න OrderedDict?
උපරිම

VGVelascoh ඇයි නිර්මාණය නොකරන්නේ newlist = [], ඊට newlist.append(array[i])පෙර del array[i]?
උපරිම

2
මෙය බොහෝ විට කාලය අකාර්යක්ෂම බව සලකන්න: list()සම්බන්ධිත ලැයිස්තුවක් නම්, අහඹු ප්‍රවේශය මිල අධිකය, list()අරාව නම්, මකාදැමීම මිල අධික බැවින් පහත සඳහන් සියලු අංග ඉදිරියට ගෙනයාමට අවශ්‍ය වේ. සම්බන්ධිත ලැයිස්තු ක්‍රියාත්මක කිරීම සඳහා යහපත් ක්‍රියාකාරකයෙකුට හොඳ දේ කළ හැකිය. කෙසේ වෙතත් මෙය අභ්‍යවකාශ කාර්යක්ෂම විය හැකිය.
සිරෝ සැන්ටිලි 郝海东 冠状 病 六四 事件 法轮功

10

වත්මන් ලැයිස්තු අයිතමය අපේක්ෂිත නිර්ණායක සපුරාලන්නේ නම් නව ලැයිස්තුවක් නිර්මාණය කිරීම බුද්ධිමත් විය හැකිය.

නිසා:

for item in originalList:
   if (item != badValue):
        newList.append(item)

නව ලැයිස්තුවේ නම සමඟ සමස්ත ව්‍යාපෘතියම නැවත කේත කිරීම වළක්වා ගැනීමට:

originalList[:] = newList

සටහන, පයිතන් ප්‍රලේඛනයෙන්:

copy.copy (x) x හි නොගැඹුරු පිටපතක් ආපසු එවන්න.

copy.deepcopy (x) x හි ගැඹුරු පිටපතක් ලබා දෙන්න.


3
මීට වසර ගණනාවකට පෙර පිළිගත් පිළිතුරෙහි නොතිබූ නව තොරතුරු මෙය එකතු නොකරයි.
මාර්ක් අමරි

2
එය සරල හා ගැටලුවක් දෙස බැලීමට තවත් ක්‍රමයක් @ මාර්ක් අමරි. සම්පීඩිත කේතීකරණ වාක්‍ය ඛණ්ඩයට අකමැති අයට එය අඩු ensed නීභවනයකි.
ntk4

9

මෙම පිළිතුර මුලින් ලියා ඇත්තේ එතැන් සිට අනුපිටපතක් ලෙස සලකුණු කර ඇති ප්‍රශ්නයකට පිළිතුරු වශයෙනි: පයිතන් ලැයිස්තුවෙන් ඛණ්ඩාංක ඉවත් කිරීම

ඔබගේ කේතයේ ගැටළු දෙකක් තිබේ:

1) ඉවත් කිරීම () භාවිතා කරන විට, ඔබ පූර්ණ සංඛ්‍යාවක් ඉවත් කිරීමට උත්සාහ කරන අතර ඔබට ටුපල් එකක් ඉවත් කිරීමට අවශ්‍ය වේ.

2) for loop ඔබේ ලැයිස්තුවේ ඇති අයිතම මඟ හරිනු ඇත.

අපි ඔබේ කේතය ක්‍රියාත්මක කරන විට කුමක් සිදුවේදැයි බලමු:

>>> L1 = [(1,2), (5,6), (-1,-2), (1,-2)]
>>> for (a,b) in L1:
...   if a < 0 or b < 0:
...     L1.remove(a,b)
... 
Traceback (most recent call last):
  File "<stdin>", line 3, in <module>
TypeError: remove() takes exactly one argument (2 given)

පළමු ගැටළුව නම් () ඉවත් කිරීම සඳහා ඔබ 'a' සහ 'b' යන දෙකම පසුකර යාමයි, නමුත් ඉවත් කරන්න () පිළිගන්නේ තනි තර්කයක් පමණි. ඔබගේ ලැයිස්තුව සමඟ නිසියාකාරව වැඩ කිරීම සඳහා අපි ඉවත් කිරීම () ලබා ගන්නේ කෙසේද? ඔබගේ ලැයිස්තුවේ එක් එක් අංග මොනවාදැයි අපට සොයා ගැනීමට අවශ්‍යය. මෙම අවස්ථාවේ දී, සෑම එකක්ම ටුපල් ය. මෙය බැලීමට, අපි ලැයිස්තුවේ එක් අංගයකට ප්‍රවේශ වෙමු (සුචිගත කිරීම 0 සිට ආරම්භ වේ):

>>> L1[1]
(5, 6)
>>> type(L1[1])
<type 'tuple'>

ආහා! L1 හි සෑම මූලද්‍රව්‍යයක්ම ඇත්ත වශයෙන්ම ටුපල් ය. () ඉවත් කිරීමට අප සමත් විය යුත්තේ එයයි. පයිතන්හි ටුපල් ඉතා පහසුය, ඒවා හුදෙක් වරහන් තුළ අගයන් ඇතුළත් කිරීමෙන් සෑදී ඇත. "a, b" යනු ටුපල් එකක් නොවේ, නමුත් "(a, b)" යනු ටුපල් ය. එබැවින් අපි ඔබේ කේතය වෙනස් කර නැවත එය ක්‍රියාත්මක කරමු:

# The remove line now includes an extra "()" to make a tuple out of "a,b"
L1.remove((a,b))

මෙම කේතය කිසිදු දෝෂයකින් තොරව ක්‍රියාත්මක වේ, නමුත් එය ප්‍රතිදානය කරන ලැයිස්තුව දෙස බලමු:

L1 is now: [(1, 2), (5, 6), (1, -2)]

(1, -2) තවමත් ඔබේ ලැයිස්තුවේ ඇත්තේ ඇයි? විශේෂ අවධානයක් නොමැතිව ඉතා නරක අදහසකි. (1, -2) ලැයිස්තුවේ රැඳී සිටීමට හේතුව නම්, ලැයිස්තුවේ ඇති එක් එක් අයිතමයේ පිහිටීම් for for loop හි පුනරාවර්තන අතර වෙනස් වීමයි. අපි ඉහත කේතය දිගු ලැයිස්තුවක් පෝෂණය කළහොත් කුමක් සිදුවේදැයි බලමු:

L1 = [(1,2),(5,6),(-1,-2),(1,-2),(3,4),(5,7),(-4,4),(2,1),(-3,-3),(5,-1),(0,6)]
### Outputs:
L1 is now: [(1, 2), (5, 6), (1, -2), (3, 4), (5, 7), (2, 1), (5, -1), (0, 6)]

එම ප්‍රති result ලයෙන් ඔබට අනුමාන කළ හැකි පරිදි, කොන්දේසි සහිත ප්‍රකාශය සත්‍ය ලෙස තක්සේරු කර ලැයිස්තු අයිතමයක් ඉවත් කරන සෑම අවස්ථාවකම, ලූපයේ ඊළඟ ක්‍රියාකාරීත්වය ලැයිස්තුවේ ඊළඟ අයිතමය ඇගයීම මඟ හරිනු ඇත, මන්ද එහි අගයන් දැන් විවිධ දර්ශකවල පිහිටා ඇත.

වඩාත්ම අවබෝධාත්මක විසඳුම වන්නේ ලැයිස්තුව පිටපත් කිරීම, පසුව මුල් ලැයිස්තුවට නැවත නැවත පිටපත් කිරීම පමණි. ඔබට මේ ආකාරයට එසේ කිරීමට උත්සාහ කළ හැකිය:

L2 = L1
for (a,b) in L1:
    if a < 0 or b < 0 :
        L2.remove((a,b))
# Now, remove the original copy of L1 and replace with L2
print L2 is L1
del L1
L1 = L2; del L2
print ("L1 is now: ", L1)

කෙසේ වෙතත්, ප්‍රතිදානය පෙරට සමාන වේ:

'L1 is now: ', [(1, 2), (5, 6), (1, -2), (3, 4), (5, 7), (2, 1), (5, -1), (0, 6)]

මෙයට හේතුව අප L2 නිර්මාණය කරන විට පයිතන් ඇත්ත වශයෙන්ම නව වස්තුවක් නිර්මාණය නොකිරීමයි. ඒ වෙනුවට, එය හුදෙක් L2 යන්න L1 හා සමාන වස්තුවකට යොමු කරයි. අපට මෙය "is" සමඟ සත්‍යාපනය කළ හැකි අතර එය හුදෙක් "සමාන" (==) ට වඩා වෙනස් වේ.

>>> L2=L1
>>> L1 is L2
True

Copy.copy () භාවිතයෙන් අපට සත්‍ය පිටපතක් සෑදිය හැකිය. එවිට සියල්ල අපේක්ෂා කළ පරිදි ක්‍රියාත්මක වේ:

import copy
L1 = [(1,2), (5,6),(-1,-2), (1,-2),(3,4),(5,7),(-4,4),(2,1),(-3,-3),(5,-1),(0,6)]
L2 = copy.copy(L1)
for (a,b) in L1:
    if a < 0 or b < 0 :
        L2.remove((a,b))
# Now, remove the original copy of L1 and replace with L2
del L1
L1 = L2; del L2
>>> L1 is now: [(1, 2), (5, 6), (3, 4), (5, 7), (2, 1), (0, 6)]

අවසාන වශයෙන්, L1 හි සම්පූර්ණයෙන්ම නව පිටපතක් සෑදීමට වඩා පිරිසිදු විසඳුමක් තිබේ. ආපසු හරවන ලද () ශ්‍රිතය:

L1 = [(1,2), (5,6),(-1,-2), (1,-2),(3,4),(5,7),(-4,4),(2,1),(-3,-3),(5,-1),(0,6)]
for (a,b) in reversed(L1):
    if a < 0 or b < 0 :
        L1.remove((a,b))
print ("L1 is now: ", L1)
>>> L1 is now: [(1, 2), (5, 6), (3, 4), (5, 7), (2, 1), (0, 6)]

අවාසනාවට, ආපසු හැරවූ () ක්‍රියා කරන ආකාරය මට ප්‍රමාණවත් ලෙස විස්තර කළ නොහැක. ලැයිස්තුවක් සම්මත කළ විට එය 'listreverseiterator' වස්තුවක් ලබා දෙයි. ප්‍රායෝගික අරමුණු සඳහා, එහි තර්කයේ ප්‍රතිලෝම පිටපතක් නිර්මාණය කිරීමක් ලෙස ඔබට සිතිය හැකිය. මම නිර්දේශ කරන විසඳුම මෙයයි.


4

පුනරාවර්තනයේදී ඔබට වෙනත් දෙයක් කිරීමට අවශ්‍ය නම්, දර්ශකය (එය යොමු කිරීමට ඔබට හැකියාව ඇති බව සහතික කරයි, උදාහරණයක් ලෙස ඔබට නියෝග ලැයිස්තුවක් තිබේ නම්) සහ සත්‍ය ලැයිස්තු අයිතම අන්තර්ගතය ලබා ගැනීම සතුටක් විය හැකිය.

inlist = [{'field1':10, 'field2':20}, {'field1':30, 'field2':15}]    
for idx, i in enumerate(inlist):
    do some stuff with i['field1']
    if somecondition:
        xlist.append(idx)
for i in reversed(xlist): del inlist[i]

enumerateඔබට එකවරම අයිතමයට සහ දර්ශකයට ප්‍රවේශය ලබා දේ. reversedඑසේ නම් ඔබ පසුව මකා දැමීමට යන දර්ශක ඔබ මත වෙනස් නොවේ.


වෙනත් ආකාරයක ලැයිස්තුවකට වඩා ඔබට නියෝග ලැයිස්තුවක් ඇති අවස්ථාවකදී දර්ශකය ලබා ගැනීම වඩා වැදගත් වන්නේ ඇයි? මට කියන්න පුළුවන් තරම් මේක තේරුමක් නැහැ.
මාර්ක් අමරි

4

මෙහි ඇති බොහෝ පිළිතුරු වලට අවශ්‍ය වන්නේ ඔබ ලැයිස්තුවේ පිටපතක් සෑදීමයි. මට භාවිතා කිරීමේ නඩුවක් තිබුනේ ලැයිස්තුව තරමක් දිගු (අයිතම 110K) වන අතර ඒ වෙනුවට ලැයිස්තුව අඩු කිරීම වඩා හොඳය.

පළමුවෙන්ම ඔබට foreach loop වෙනුවට while loop වෙනුවට ආදේශ කළ යුතුය ,

i = 0
while i < len(somelist):
    if determine(somelist[i]):
         del somelist[i]
    else:
        i += 1

iපරණ අයිතමය මකා දැමූ පසු, එකම අයිඩෙක්ස් වෙතින් නව අයිතමයේ වටිනාකම ලබා ගැනීමට ඔබට අවශ්‍ය නිසා, අයිෆ් බ්ලොක් එකේ වටිනාකම වෙනස් නොවේ.


3

ඔබට ප්‍රතිලෝමව ලූප් කිරීම සඳහා උත්සාහ කළ හැකිය, එබැවින් සමහරක්_ ලැයිස්තුවක් සඳහා ඔබ මෙවැනි දෙයක් කරනු ඇත:

list_len = len(some_list)
for i in range(list_len):
    reverse_i = list_len - 1 - i
    cur = some_list[reverse_i]

    # some logic with cur element

    if some_condition:
        some_list.pop(reverse_i)

මේ ආකාරයෙන් දර්ශකය පෙළගස්වා ඇති අතර ලැයිස්තු යාවත්කාලීනයන්ගෙන් පීඩා විඳින්නේ නැත (ඔබ ව්‍යංජන මූලද්‍රව්‍යය පොප් කළත් නැතත්).


කට ප්රහාරක reversed(list(enumerate(some_list)))දර්ශක ඔබ ගණනය වඩා සරල වනු ඇත.
මාර්ක් අමරි

Ark මාක්අමරි ඔබට ලැයිස්තුව මේ ආකාරයෙන් වෙනස් කළ හැකි යැයි නොසිතයි.
ක්වෙක්වෙග්


3

කළ හැකි එක් විසඳුමක්, ඔබට අවශ්‍ය නම් සමහර දේවල් ඉවත් කිරීම පමණක් නොව, එක් අංගයක් තුළ ඇති සියලුම අංග සමඟ යමක් කරන්න:

alist = ['good', 'bad', 'good', 'bad', 'good']
i = 0
for x in alist[:]:
    if x == 'bad':
        alist.pop(i)
        i -= 1
    # do something cool with x or just print x
    print(x)
    i += 1

ඔබ සැබවින්ම අවබෝධය භාවිතා කළ යුතුය. ඒවා තේරුම් ගැනීමට වඩා පහසුය.
බීෆ්ස්ටර්

මට badදේවල් ඉවත් කිරීමට අවශ්‍ය නම් , ඒ සමඟ යමක් කරන්න සහ goodඑක් පුඩුවක් තුළ ඇති දේවල් සමඟ යමක් කරන්න ?
ඇලෙක්සි

1
ඇත්ත වශයෙන්ම, මෙහි යම් දක්ෂතාවයක් ඇති බව මම තේරුම් ගත්තා ඔබ විවෘත පෙත්තක් සමඟ ලැයිස්තුවේ පිටපතක් සාදයි ( alist[:]) තවද ඔබ විසිතුරු යමක් කරන බැවින් එයට ඇත්ත වශයෙන්ම භාවිත අවස්ථාවක් තිබේ. හොඳ සංශෝධනයක් හොඳයි. මගේ උන්නතිය ගන්න.
බීෆ්ස්ටර්

3

ලූපය දර්ශකය හරහා නැවත යෙදෙන නිසා ..

ඔබට ලැයිස්තුවක් ඇති බව සලකන්න,

[5, 7, 13, 29, 65, 91]

ඔබ ලැයිස්තු විචල්‍යය භාවිතා කර ඇත lis. ඉවත් කිරීමට ඔබ එයම භාවිතා කරයි ..

ඔබේ විචල්‍යය

lis = [5, 7, 13, 29, 35, 65, 91]
       0  1   2   3   4   5   6

5 වන ක්‍රියාවලිය අතරතුර,

ඔබගේ අංක 35 ප්‍රමුඛයක් නොවූ බැවින් ඔබ එය ලැයිස්තුවකින් ඉවත් කළේය.

lis.remove(y)

ඉන්පසු ඊළඟ අගය (65) පෙර දර්ශකය එකට යනවා.

lis = [5, 7, 13, 29, 65, 91]
       0  1   2   3   4   5

එබැවින් 4 වන පුනරාවර්තනය සිදු කරන ලද දර්ශකය 5 වන ස්ථානයට ගෙන ගියේය.

ඔබගේ ලූපය පෙර දර්ශකයට ගෙන ගිය දා සිට එය 65 ක් ආවරණය නොකරන්නේ එබැවිනි.

එබැවින් ඔබ පිටපත වෙනුවට මුල් පිටපත සඳහන් වෙනත් විචල්‍යයකට ලැයිස්තුව යොමු නොකළ යුතුය.

ite = lis #dont do it will reference instead copy

එබැවින් ලැයිස්තුවේ පිටපතක් භාවිතා කරන්න list[::]

දැන් ඔබ එය දෙනු ඇත,

[5, 7, 13, 29]

ගැටළුව වන්නේ ඔබ නැවත ක්‍රියාවට නැංවීමේදී ලැයිස්තුවකින් අගයක් ඉවත් කළහොත් ඔබේ ලැයිස්තු දර්ශකය බිඳ වැටෙනු ඇත.

ඒ නිසා ඔබට ඒ වෙනුවට අවබෝධය උත්සාහ කළ හැකිය.

ලැයිස්තුව, ටුපල්, ඩික්ට්, ස්ට්‍රිං යනාදී සියලු ක්‍රියාකාරී දේ සඳහා සහය දක්වයි


2

මට සමාන දෙයක් කිරීමට අවශ්‍ය වූ අතර මගේ නඩුවේ ගැටළුව මතකයයි - ලැයිස්තුවක් තුළ දත්ත සමුදායන් කිහිපයක් ඒකාබද්ධ කිරීමට මට අවශ්‍ය විය, ඒවා සමඟ යම් යම් දේවල් කළ පසු, නව වස්තුවක් ලෙස, සහ මා ඒකාබද්ධ කරන සෑම ප්‍රවේශයකින්ම ඉවත් වීමට අවශ්‍ය විය. ඒවා සියල්ලම අනුපිටපත් කිරීමෙන් හා මතකය පුපුරවා ගැනීමෙන් වළකින්න. මගේ නඩුවේදී ලැයිස්තුවක් වෙනුවට ශබ්ද කෝෂයක වස්තූන් තිබීම හොඳින් ක්‍රියාත්මක විය:

`` `

k = range(5)
v = ['a','b','c','d','e']
d = {key:val for key,val in zip(k, v)}

print d
for i in range(5):
    print d[i]
    d.pop(i)
print d

`` `


2

TLDR:

මම ඔබට මෙය කිරීමට ඉඩ දෙන පුස්තකාලයක් ලිවීය:

from fluidIter import FluidIterable
fSomeList = FluidIterable(someList)  
for tup in fSomeList:
    if determine(tup):
        # remove 'tup' without "breaking" the iteration
        fSomeList.remove(tup)
        # tup has also been removed from 'someList'
        # as well as 'fSomeList'

හැකි නම් වෙනත් ක්‍රමයක් භාවිතා කිරීම වඩාත් සුදුසුය, එය නැවත ක්‍රියාවට නැංවීමේදී ඔබේ ක්‍රියාකාරීත්වය වෙනස් කිරීම අවශ්‍ය නොවේ, නමුත් සමහර ඇල්ගොරිතම සඳහා එය කෙළින්ම ඉදිරියට නොයනු ඇත. මුල් ප්‍රශ්නයේ විස්තර කර ඇති කේත රටාව ඔබට සැබවින්ම අවශ්‍ය බව ඔබට විශ්වාස නම්, එය කළ හැකිය.

ලැයිස්තු පමණක් නොව සියලු විකෘති අනුක්‍රමයන් මත ක්‍රියා කළ යුතුය.


සම්පූර්ණ පිළිතුර:

සංස්කරණය කරන්න: මෙම පිළිතුරේ ඇති අවසාන කේත උදාහරණය මඟින් ඔබට සමහර විට ලැයිස්තු අවබෝධයක් භාවිතා කරනවාට වඩා ලැයිස්තුවක් වෙනස් කිරීමට අවශ්‍ය වන්නේ ඇයිද යන්න භාවිතා කිරීමේ අවස්ථාවක් ලබා දේ. පිළිතුරු වල පළමු කොටස අරාව තැනින් වෙනස් කළ හැකි ආකාරය පිළිබඳ නිබන්ධනයක් ලෙස සේවය කරයි .

විසඳුම සිට පහත සඳහන් මෙම senderle වෙතින් පිළිතුරක් (අ සම්බන්ධ ප්රශ්නය සඳහා). නවීකරණය කරන ලද ලැයිස්තුවක් හරහා නැවත යෙදෙන අතරතුර අරාව දර්ශකය යාවත්කාලීන කරන්නේ කෙසේද යන්න පැහැදිලි කරයි. ලැයිස්තුව වෙනස් කළද අරාව දර්ශකය නිවැරදිව නිරීක්ෂණය කිරීම සඳහා පහත විසඳුම සැලසුම් කර ඇත.

බාගත fluidIter.pyසිට මෙහි https://github.com/alanbacon/FluidIterator , එය එසේ GIT ස්ථාපනය කිරීමට කිසිදු අවශ්යතාවයක් පමණක් තනි ගොනුවකි. ස්ථාපකයක් නොමැති බැවින් ගොනුව ඔබේම පයිතන් මාවතේ ඇති බවට වග බලා ගත යුතුය. කේතය පයිතන් 3 සඳහා ලියා ඇති අතර එය පයිතන් 2 හි පරීක්ෂා කර නොමැත.

from fluidIter import FluidIterable
l = [0,1,2,3,4,5,6,7,8]  
fluidL = FluidIterable(l)                       
for i in fluidL:
    print('initial state of list on this iteration: ' + str(fluidL)) 
    print('current iteration value: ' + str(i))
    print('popped value: ' + str(fluidL.pop(2)))
    print(' ')

print('Final List Value: ' + str(l))

මෙය පහත ප්‍රතිදානය නිපදවනු ඇත:

initial state of list on this iteration: [0, 1, 2, 3, 4, 5, 6, 7, 8]
current iteration value: 0
popped value: 2

initial state of list on this iteration: [0, 1, 3, 4, 5, 6, 7, 8]
current iteration value: 1
popped value: 3

initial state of list on this iteration: [0, 1, 4, 5, 6, 7, 8]
current iteration value: 4
popped value: 4

initial state of list on this iteration: [0, 1, 5, 6, 7, 8]
current iteration value: 5
popped value: 5

initial state of list on this iteration: [0, 1, 6, 7, 8]
current iteration value: 6
popped value: 6

initial state of list on this iteration: [0, 1, 7, 8]
current iteration value: 7
popped value: 7

initial state of list on this iteration: [0, 1, 8]
current iteration value: 8
popped value: 8

Final List Value: [0, 1]

ඉහත අපි popතරල ලැයිස්තු වස්තුව මත ක්‍රමය භාවිතා කර ඇත. වෙනත් පොදු iterable ක්රම ද එලෙස ක්රියාත්මක වේ del fluidL[i], .remove, .insert, .append, .extend. පෙති භාවිතයෙන් ලැයිස්තුව වෙනස් කළ හැකිය ( sortසහ reverseක්‍රම ක්‍රියාත්මක නොවේ).

එකම කොන්දේසිය නම්, ඔබ යම් ස්ථානයක ලැයිස්තුව වෙනස් කළ යුතු අතර, කිසියම් අවස්ථාවක fluidLහෝ lවෙනත් ලැයිස්තු වස්තුවකට නැවත පවරා ඇත්නම් කේතය ක්‍රියා නොකරනු ඇත. මුල් fluidLවස්තුව for for loop විසින් තවමත් භාවිතා කරනු ඇති නමුත් අපට එය වෙනස් කිරීමට හැකියාවක් නැත.

එනම්

fluidL[2] = 'a'   # is OK
fluidL = [0, 1, 'a', 3, 4, 5, 6, 7, 8]  # is not OK

ලැයිස්තුවේ වත්මන් දර්ශක අගයට ප්‍රවේශ වීමට අපට අවශ්‍ය නම් අපට ගණන් බැලීම භාවිතා කළ නොහැක, මන්ද මෙය ගණනය කරනුයේ for loop සඳහා කොපමණ වාරයක් ධාවනය වී ඇත්ද යන්නයි. ඒ වෙනුවට අපි iterator වස්තුව කෙලින්ම භාවිතා කරමු.

fluidArr = FluidIterable([0,1,2,3])
# get iterator first so can query the current index
fluidArrIter = fluidArr.__iter__()
for i, v in enumerate(fluidArrIter):
    print('enum: ', i)
    print('current val: ', v)
    print('current ind: ', fluidArrIter.currentIndex)
    print(fluidArr)
    fluidArr.insert(0,'a')
    print(' ')

print('Final List Value: ' + str(fluidArr))

මෙය පහත සඳහන් දෑ ප්‍රතිදානය කරයි:

enum:  0
current val:  0
current ind:  0
[0, 1, 2, 3]

enum:  1
current val:  1
current ind:  2
['a', 0, 1, 2, 3]

enum:  2
current val:  2
current ind:  4
['a', 'a', 0, 1, 2, 3]

enum:  3
current val:  3
current ind:  6
['a', 'a', 'a', 0, 1, 2, 3]

Final List Value: ['a', 'a', 'a', 'a', 0, 1, 2, 3]

මෙම FluidIterableපන්ති පමණක් මුල් ලැයිස්තුව වස්තුව සඳහා දවටනය සපයයි. මුල් වස්තුව ද්‍රව වස්තුවක දේපලක් ලෙස ප්‍රවේශ විය හැකිය:

originalList = fluidArr.fixedIterable

තවත් උදාහරණ / පරීක්ෂණ if __name__ is "__main__":පතුලේ ඇති කොටසේ සොයාගත හැකිය fluidIter.py. විවිධ අවස්ථා වලදී සිදුවන්නේ කුමක්ද යන්න පැහැදිලි කරන බැවින් මේවා බැලීම වටී. වැනි: පෙත්තක් භාවිතයෙන් ලැයිස්තුවේ විශාල කොටස් ප්‍රතිස්ථාපනය කිරීම. නැතහොත් ලූප සඳහා කූඩුවල එකම නැවත භාවිතා කළ හැකි (සහ වෙනස් කිරීම) භාවිතා කිරීම.

ආරම්භ කිරීමට මා ප්‍රකාශ කළ පරිදි: මෙය ඔබේ කේතයේ කියවීමේ හැකියාව රිදවන සහ නිදොස්කරණය කිරීම වඩාත් අපහසු කරන සංකීර්ණ විසඳුමකි. එබැවින් ඩේවිඩ් රස්නික්ගේ පිළිතුරෙහි සඳහන් ලැයිස්තු අවබෝධය වැනි වෙනත් විසඳුම් පළමුව සලකා බැලිය යුතුය. මෙසේ පැවසුවහොත්, මෙම පංතිය මට ප්‍රයෝජනවත් වූ අවස්ථා සහ මකාදැමීමට අවශ්‍ය මූලද්‍රව්‍යයන්ගේ දර්ශක නිරීක්ෂණය කිරීමට වඩා භාවිතා කිරීමට පහසු වූ අවස්ථා මම සොයාගෙන ඇත.


සංස්කරණය කරන්න: අදහස් දැක්වීම්වල සඳහන් කර ඇති පරිදි, මෙම පිළිතුර මගින් මෙම ප්‍රවේශය මගින් විසඳුමක් සපයන ගැටලුවක් ඉදිරිපත් නොකරයි. මම එය මෙහි ආමන්ත්‍රණය කිරීමට උත්සාහ කරමි:

ලැයිස්තු අවබෝධය නව ලැයිස්තුවක් ජනනය කිරීමට ක්‍රමයක් සපයන නමුත් මෙම ප්‍රවේශයන් සමස්තයක් ලෙස ලැයිස්තුවේ වත්මන් තත්වයට වඩා හුදකලා ලෙස එක් එක් මූලද්‍රව්‍ය දෙස බැලීමට නැඹුරු වේ.

එනම්

newList = [i for i in oldList if testFunc(i)]

නමුත් testFuncරඳා පැවතීමේ ප්‍රති result ලය newListදැනටමත් එකතු කර ඇති මූලද්‍රව්‍ය මත රඳා පවතී නම් කුමක් කළ යුතුද? නැතහොත් එහි ඇති මූලද්‍රව්‍ය oldListඊළඟට එකතු කළ හැකිද? ලැයිස්තු අවබෝධය භාවිතා කිරීමට තවමත් ක්‍රමයක් තිබිය හැකි නමුත් එය එහි අලංකාරය නැති කර ගැනීමට පටන් ගනී, මට නම් ලැයිස්තුවක් වෙනස් කිරීම පහසු යැයි මට හැඟේ.

ඉහත කේතය ඉහත ගැටලුවෙන් පෙළෙන ඇල්ගොරිතමයක එක් උදාහරණයකි. ඇල්ගොරිතම මඟින් ලැයිස්තුවක් අඩු කරනු ඇති අතර එමඟින් කිසිදු මූලද්‍රව්‍යයක් වෙනත් මූලද්‍රව්‍යයක ගුණකයක් නොවේ.

randInts = [70, 20, 61, 80, 54, 18, 7, 18, 55, 9]
fRandInts = FluidIterable(randInts)
fRandIntsIter = fRandInts.__iter__()
# for each value in the list (outer loop)
# test against every other value in the list (inner loop)
for i in fRandIntsIter:
    print(' ')
    print('outer val: ', i)
    innerIntsIter = fRandInts.__iter__()
    for j in innerIntsIter:
        innerIndex = innerIntsIter.currentIndex
        # skip the element that the outloop is currently on
        # because we don't want to test a value against itself
        if not innerIndex == fRandIntsIter.currentIndex:
            # if the test element, j, is a multiple 
            # of the reference element, i, then remove 'j'
            if j%i == 0:
                print('remove val: ', j)
                # remove element in place, without breaking the
                # iteration of either loop
                del fRandInts[innerIndex]
            # end if multiple, then remove
        # end if not the same value as outer loop
    # end inner loop
# end outerloop

print('')
print('final list: ', randInts)

ප්‍රතිදානය සහ අවසාන අඩු කළ ලැයිස්තුව පහත දැක්වේ

outer val:  70

outer val:  20
remove val:  80

outer val:  61

outer val:  54

outer val:  18
remove val:  54
remove val:  18

outer val:  7
remove val:  70

outer val:  55

outer val:  9
remove val:  18

final list:  [20, 61, 7, 55, 9]

මෙය ඕනෑවට වඩා සැලසුම් කර ඇත්දැයි කීමට අපහසු බැවින් එය විසඳීමට උත්සාහ කරන්නේ කුමන ගැටලුවද යන්න පැහැදිලි නැත; මෙම ප්‍රවේශය භාවිතයෙන් මූලද්‍රව්‍ය ඉවත් කිරීමෙන් අත් කරගත නොහැකි some_list[:] = [x for x in some_list if not some_condition(x)]වන්නේ කුමක්ද? එයට පිළිතුරක් නොමැතිව, ඔබේ පේළි 600 ක පුස්තකාලය යතුරු ලියනය කිරීමෙන් හා අදහස් දැක්වීමේ කේතයෙන් බාගත කිරීම සහ භාවිතා කිරීම ඔවුන්ගේ ගැටළුවට එක් ලයිනර් යන්ත්‍රයකට වඩා හොඳ විසඳුමක් යැයි කිසිවෙකු විශ්වාස කළ යුත්තේ ඇයි? -1.
මාර්ක් අමරි

Ark මාක් අමරි. අයිතමයක් පමණක් නොව, ලැයිස්තුවේ ඇති වෙනත් අයිතමයක තත්වය හෝ ලැයිස්තුවේ තත්වය මත පදනම්ව අයිතමයක් ඉවත් කළ යුතුද (හෝ එකතු කළ යුතුද නැතහොත් ගෙන යා යුතුද) යන්න තීරණය කිරීමට උත්සාහ කරන විට මෙය ප්‍රධාන වේ. සමස්ත. උදාහරණයක් ලෙස, ලැයිස්තු අවබෝධය සමඟ වෙනස් ලැයිස්තු මූලද්‍රව්‍යයක් some_list[:] = [x for x in some_list if not some_condition(y)]කොහෙන්දැයි ලිවීමට නොහැකිය . ලිවීමට ද නොහැකි වනු ඇත . yxsome_list[:] = [x for x in some_list if not some_condition(intermediateStateOf_some_list)]
අනුනාද

2

අනෙක් පිළිතුරු නිවැරදියි, සාමාන්‍යයෙන් ඔබ නැවත කියවන ලැයිස්තුවකින් මකා දැමීම නරක අදහසකි. ප්‍රතිලෝම පුනරාවර්තනය මඟින් අන්තරායන් වළක්වයි, නමුත් එය කරන කේතය අනුගමනය කිරීම වඩා දුෂ්කර ය, එබැවින් සාමාන්‍යයෙන් ඔබ ලැයිස්තු අවබෝධය භාවිතා කිරීම වඩා හොඳය filter.

කෙසේ වෙතත්, ඔබ පුනරාවර්තනය වන අනුක්‍රමයකින් මූලද්‍රව්‍ය ඉවත් කිරීම ආරක්ෂිත වන එක් අවස්ථාවක් තිබේ: ඔබ නැවත යෙදෙන අතරතුර එක් අයිතමයක් පමණක් ඉවත් කරන්නේ නම්. මෙය a returnහෝ a භාවිතා කර සහතික කළ හැකිය break. උදාහරණයක් වශයෙන්:

for i, item in enumerate(lst):
    if item % 4 == 0:
        foo(item)
        del lst[i]
        break

කිසියම් කොන්දේසියක් සපුරාලන ලැයිස්තුවක පළමු අයිතමයට අතුරු ආබාධ ඇතිව යම් යම් ක්‍රියාකාරකම් සිදු කරන විට සහ ලැයිස්තුවෙන් එම අයිතමය වහාම ඉවත් කරන විට මෙය ලැයිස්තුව අවබෝධ කර ගැනීමට වඩා බොහෝ විට තේරුම් ගැනීම පහසුය.


2

වඩාත්ම ඵලදායී ක්රමය ලැයිස්තුව අවබෝධය වන්නේ, බොහෝ මිනිසුන් සිය නඩුව, ඇත්ත වශයෙන්, එය ද ලබා ගැනීමට හොඳ ක්රමයක් වන පෙන්වන්න iteratorහරහා filter.

Filterශ්‍රිතයක් සහ අනුක්‍රමයක් ලැබේ. Filterඅනෙක් අතට එක් එක් මූලද්රව්යය සඳහා සම්මත කාර්යය අදාළ වන අතර, එසේ නම් මෙම උත්සවයට ආපසු ලැබෙන අගය ද යන්න මත පදනම්ව මූලද්රව්ය රඳවා හෝ අවලංගු කිරීම සඳහා යන්න තීරණය Trueහෝ False.

උදාහරණයක් ඇත (ටුපල් එකේ ඇති අන්තරායන් ලබා ගන්න):

list(filter(lambda x:x%2==1, (1, 2, 4, 5, 6, 9, 10, 15)))  
# result: [1, 5, 9, 15]

අවවාදයයි: ඔබට අනුකාරක හැසිරවිය නොහැක. අනුකාරක සමහර විට අනුපිළිවෙලට වඩා හොඳයි.


2

නැවත සැකසීමේදී ඔබට ලැයිස්තුවකින් මූලද්‍රව්‍ය මකා දැමීමට අවශ්‍ය නම්, ටික වේලාවක් භාවිතා කරන්න, එවිට එක් එක් මකාදැමීමෙන් පසු වත්මන් දර්ශකය සහ අවසන් දර්ශකය වෙනස් කළ හැකිය.

උදාහරණයක්:

i = 0
length = len(list1)

while i < length:
    if condition:
        list1.remove(list1[i])
        i -= 1
        length -= 1

    i += 1

1

ඔබේ ගැටලුව විසඳීම සඳහා ප්‍රවේශයන් තුනක් ගැන මට සිතිය හැකිය. උදාහරණයක් ලෙස, මම අහඹු ලෙස ටුපල් ලැයිස්තුවක් සාදමි somelist = [(1,2,3), (4,5,6), (3,6,6), (7,8,9), (15,0,0), (10,11,12)]. මම තෝරා ගන්නා කොන්දේසිය එයයි sum of elements of a tuple = 15. අවසාන ලැයිස්තුවේ අපට ඇත්තේ 15 ට සමාන නොවන ටුපල් පමණි.

මා තෝරාගෙන ඇත්තේ අහඹු ලෙස තෝරාගත් උදාහරණයකි. වෙනස් නිදහස් වන්න ඇති tuples ලැයිස්තුව හා තත්ත්වය මම තෝරාගෙන ඇති බව.

ක්රමය 1.> ඔබ යෝජනා කළ රාමුව භාවිතා කරන්න (එහිදී එකක් සඳහා ලූපයක් තුළ කේතයක් පුරවනු ලැබේ). delඑම කොන්දේසිය සපුරාලන ටුපල් එකක් මකා දැමීමට මම කුඩා කේතයක් භාවිතා කරමි . කෙසේ වෙතත්, අඛණ්ඩව තබා ඇති ටුපල් දෙකක් ලබා දී ඇති කොන්දේසිය සපුරාලන්නේ නම් මෙම ක්‍රමයට ටුපල් එකක් (එම කොන්දේසිය තෘප්තිමත් වන) මග හැරෙනු ඇත.

for tup in somelist:
    if ( sum(tup)==15 ): 
        del somelist[somelist.index(tup)]

print somelist
>>> [(1, 2, 3), (3, 6, 6), (7, 8, 9), (10, 11, 12)]

ක්රමය 2.> දී ඇති කොන්දේසිය සපුරා නොමැති මූලද්රව්ය (ටුපල්) අඩංගු නව ලැයිස්තුවක් සාදන්න (මෙය ලබා දී ඇති කොන්දේසිය සපුරා ඇති ලැයිස්තුවේ මූලද්රව්ය ඉවත් කිරීම හා සමාන වේ). ඒ සඳහා කේතය පහත දැක්වේ:

newlist1 = [somelist[tup] for tup in range(len(somelist)) if(sum(somelist[tup])!=15)]

print newlist1
>>>[(1, 2, 3), (7, 8, 9), (10, 11, 12)]

ක්රමය 3.> දී ඇති කොන්දේසිය සපුරා ඇති දර්ශක සොයා ගන්න, ඉන්පසු එම දර්ශකවලට අනුරූපව ඉවත් කිරීමේ මූලද්රව්ය (ටුපල්) භාවිතා කරන්න. ඒ සඳහා කේතය පහත දැක්වේ.

indices = [i for i in range(len(somelist)) if(sum(somelist[i])==15)]
newlist2 = [tup for j, tup in enumerate(somelist) if j not in indices]

print newlist2
>>>[(1, 2, 3), (7, 8, 9), (10, 11, 12)]

ක්රමය 1 සහ ක්රමය 2 ක්රම 3 ට වඩා වේගවත් වේ . Method1 සහ method3 method1 ට වඩා කාර්යක්ෂම වේ. මම කැමති method2 . ඉහත උදාහරණය සඳහා,time(method1) : time(method2) : time(method3) = 1 : 1 : 1.7


0

සැබවින්ම විශාල වීමට විභවයක් ඇති ඕනෑම දෙයක් සඳහා, මම පහත සඳහන් දෑ භාවිතා කරමි.

import numpy as np

orig_list = np.array([1, 2, 3, 4, 5, 100, 8, 13])

remove_me = [100, 1]

cleaned = np.delete(orig_list, remove_me)
print(cleaned)

එය සියල්ලටම වඩා සැලකිය යුතු වේගයකින් විය යුතුය.


මා මනින ලද දෙයින්, මූලද්‍රව්‍ය 20 කට වඩා වැඩි ලැයිස්තුවක් සඳහා NumPy වේගවත් වීමට පටන් ගන්නා අතර, මූලද්‍රව්‍ය 1000 සහ තවත් විශාල ලැයිස්තුවක් සඳහා> 12x වේගවත් පෙරනයක් කරා ළඟා වේ.
ජෝර්ජි

0

සමහර අවස්ථාවන්හිදී, ඔබ වරකට ලැයිස්තුවක් එක් අයිතමයක් පෙරීමට වඩා වැඩි යමක් කරන විට, ඔබට අවශ්‍ය වන්නේ නැවත කියවීමේදී ඔබේ ක්‍රියාකාරීත්වය වෙනස් වීමයි.

ලැයිස්තුව කලින් පිටපත් කිරීම වැරදියි, ආපසු හැරවීම නැවත කළ නොහැකි අතර ලැයිස්තු අවබෝධය ද විකල්පයක් නොවේ.

""" Sieve of Eratosthenes """

def generate_primes(n):
    """ Generates all primes less than n. """
    primes = list(range(2,n))
    idx = 0
    while idx < len(primes):
        p = primes[idx]
        for multiple in range(p+p, n, p):
            try:
                primes.remove(multiple)
            except ValueError:
                pass #EAFP
        idx += 1
        yield p

0

ඔබ පසුව නව ලැයිස්තුව භාවිතා කරන්නේ නම්, ඔබට හුදෙක් එලිම් එක කිසිවක් ලෙස සැකසිය නොහැක, පසුව එය පසුව ලූපයෙන් විනිශ්චය කරන්න,

for i in li:
    i = None

for elem in li:
    if elem is None:
        continue

මේ ආකාරයෙන්, ඔබට ලැයිස්තුව පිටපත් කිරීම අවශ්‍ය නොවන අතර එය තේරුම් ගැනීම පහසුය.


-1

අංක ලැයිස්තුවක් උඩු යටිකුරු කරන්න, ඔබට 3 න් බෙදිය හැකි සියල්ල ඉවත් කිරීමට අවශ්‍යය,

list_number =[i for i in range(100)]

භාවිතා කිරීමෙන් list comprehension, මෙය නව ලැයිස්තුවක් ගැන සැලකිලිමත් වන අතර නව මතක අවකාශයක් නිර්මාණය කරයි

new_list =[i for i in list_number if i%3!=0]

lambda filterශ්‍රිතය භාවිතා කිරීමෙන් , මෙය ප්‍රති list ලයක් ලෙස නව ලැයිස්තුවක් නිර්මාණය කර අනුස්මරණ අවකාශය පරිභෝජනය කරයි

new_list = list(filter(lambda x:x%3!=0, list_number))

නව ලැයිස්තුවක් සඳහා මතක ඉඩ පරිභෝජනය නොකර දැනට පවතින ලැයිස්තුව වෙනස් කරන්න

for index, value in enumerate(list_number):
    if list_number[index]%3==0:
        list_number.remove(value)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.