केवल एक बयान में पायथन सूची से कई आइटम निकालें


107

अजगर में, मुझे पता है कि किसी सूची से आइटम कैसे निकालना है।

item_list = ['item', 5, 'foo', 3.14, True]
item_list.remove('item')
item_list.remove(5)

यह उपरोक्त कोड 5 और 'आइटम' को आइटम_लिस्ट से हटा देता है। लेकिन जब हटाने के लिए बहुत सारा सामान होता है, तो मुझे कई लाइनें लिखनी होती हैं

item_list.remove("something_to_remove")

अगर मुझे पता है कि मैं जो हटा रहा हूं, उसका सूचकांक मुझे पता है:

del item_list[x]

जहाँ x उस आइटम का सूचकांक है जिसे मैं हटाना चाहता हूँ।

अगर मुझे उन सभी नंबरों का सूचकांक पता है, जिन्हें मैं निकालना चाहता हूं, तो मैं delसूचकांकों में किसी प्रकार के लूप का उपयोग करूंगा ।

लेकिन क्या होगा अगर मैं उन वस्तुओं के सूचकांकों को नहीं जानता जिन्हें मैं हटाना चाहता हूं?

मैंने कोशिश की item_list.remove('item', 'foo'), लेकिन मुझे यह कहते हुए एक त्रुटि हुई कि removeकेवल एक तर्क लेता है।

क्या एक सूची में कई वस्तुओं को एक बयान में निकालने का एक तरीका है?

पुनश्च मैं का उपयोग किया है delऔर remove। क्या कोई इन दोनों के बीच का अंतर समझा सकता है, या वे एक ही हैं?

धन्यवाद


1
अपने दूसरे प्रश्न का उत्तर देने के लिए: delकिसी वस्तु को उसके सूचकांक से हटा देता है। removeकिसी सूची का कार्य किसी वस्तु का सूचकांक पाता है और फिर delउस सूचकांक पर कॉल करता है।
— एरोन क्रिस्टियनसेन

जवाबों:


159

पायथन में, एक मौजूदा वस्तु को संशोधित करने की तुलना में एक नई वस्तु बनाना अक्सर बेहतर होता है:

item_list = ['item', 5, 'foo', 3.14, True]
item_list = [e for e in item_list if e not in ('item', 5)]

जो इसके बराबर है:

item_list = ['item', 5, 'foo', 3.14, True]
new_list = []
for e in item_list:
    if e not in ('item', 5):
        new_list.append(e)
item_list = new_list

फ़िल्टर किए गए मानों की एक बड़ी सूची के मामले में (यहां, ('item', 5)तत्व का एक छोटा सा सेट है), setप्रदर्शन में सुधार का नेतृत्व कर सकता है, क्योंकि inऑपरेशन O (1) में है:

item_list = [e for e in item_list if e not in {'item', 5}]

ध्यान दें कि, जैसा कि टिप्पणियों में बताया गया है और यहां सुझाया गया है , निम्नलिखित और भी अधिक समय बचा सकता है, प्रत्येक लूप में बनाए जाने वाले सेट से बचना:

unwanted = {'item', 5}
item_list = [e for e in item_list if e not in unwanted]

अगर याददाश्त सस्ती न हो तो एक ब्लूम फ़िल्टर भी एक अच्छा उपाय है।


मुझे पहला उत्तर पसंद है। मैं नई सूची नहीं बना रहा हूं, जो अच्छी है। धन्यवाद!
— रैंडम कोड

क्या सेट अजगर 2 में अनुकूलित है या यह केवल अजगर 3 में अनुकूलित है? मेरा मतलब है कि सेट केवल एक बार बनाया जाता है जब बायटेकोड उत्पन्न होता है?
— हर

सेट, परिभाषा के अनुसार , inऑपरेशन के लिए अनुकूलित है । चार आदिम डेटा संरचनाओं की तुलना के लिए इस बेंचमार्क को देखें । हाँ, सेट प्रत्येक लूप में बनाया गया है, जैसा कि यहाँ सुझाया गया है , फलस्वरूप जनरेटर अभिव्यक्ति में उपयोग करने के लिए समर्पित चर में सेट को बचा सकते हैं।
— अलुआरिक

@RandomCoder आप वास्तव में एक नई सूची बनाते हैं, आप सिर्फ एक नाम का पुन: उपयोग करते हैं। आप id(item_list)पहले और बाद की तुलना करके इसकी जांच कर सकते हैं item_list = [e for e in item_list if e not in ('item', 5)]। जगह में एक सूची को संशोधित करने के तरीके को देखने के लिए मेरे उत्तर की जाँच करें।
— Darkonaut

20
item_list = ['item', 5, 'foo', 3.14, True]
list_to_remove=['item', 5, 'foo']

हटाने के बाद अंतिम सूची इस प्रकार होनी चाहिए

final_list=[3.14, True]

सिंगल लाइन कोड

final_list= list(set(item_list).difference(set(list_to_remove)))

उत्पादन निम्नानुसार होगा

final_list=[3.14, True]

13
नहीं, यह सूची में आइटम को फेरबदल करता है। केवल तभी उपयोग करें जब वस्तुओं का क्रम मायने नहीं रखता है, जो यह अक्सर करता है।
— मेहतर

5
यह सूची से डुप्लिकेट को भी हटा देगा। ऐसा नहीं है कि यह उदाहरण सूची के लिए मायने रखता है
— tschale

1
यह उत्तर गलत है और गंभीर कीड़े पैदा कर सकता है, इसे क्यों उखाड़ा जाता है?
— omerfarukdogan

1
यह डुप्लिकेट को हटा देगा! जवाब गंभीर कीड़े पैदा कर सकता है, कृपया उपयोग न करें।
— user2698178

2

मुझे नहीं पता कि सभी लोग setअजगर में अद्भुत क्षमता का उल्लेख करना क्यों भूल गए । आप बस एक सेट में अपनी सूची डाल सकते हैं और फिर जो कुछ भी आप सरल अभिव्यक्ति में निकालना चाहते हैं, उसे हटा दें:

>>> item_list = ['item', 5, 'foo', 3.14, True]
>>> item_list = set(item_list) - {'item', 5}
>>> item_list
{True, 3.14, 'foo'}
>>> # you can cast it again in a list-from like so
>>> item_list = list(item_list)
>>> item_list
[True, 3.14, 'foo']

6
हालांकि वस्तुओं के क्रम को बनाए नहीं रखता है।
— एस्ट्रिड

और सूची में संभावित रूप से मौजूद डुप्लिकेट को भी हटा देगा।
— kyriakosSt

1

मैं यहाँ से अपना उत्तर दोहरा रहा हूँ क्योंकि मैंने देखा कि यह यहाँ भी फिट बैठता है। यह कई मूल्यों को हटाने या इन मूल्यों के केवल डुप्लिकेट को हटाने की अनुमति देता है और या तो एक नई सूची देता है या जगह में दी गई सूची को संशोधित करता है।


def removed(items, original_list, only_duplicates=False, inplace=False):
    """By default removes given items from original_list and returns
    a new list. Optionally only removes duplicates of `items` or modifies
    given list in place.
    """
    if not hasattr(items, '__iter__') or isinstance(items, str):
        items = [items]

    if only_duplicates:
        result = []
        for item in original_list:
            if item not in items or item not in result:
                result.append(item)
    else:
        result = [item for item in original_list if item not in items]

    if inplace:
        original_list[:] = result
    else:
        return result

डॉकस्ट्रिंग एक्सटेंशन:

"""
Examples:
---------

    >>>li1 = [1, 2, 3, 4, 4, 5, 5]
    >>>removed(4, li1)
       [1, 2, 3, 5, 5]
    >>>removed((4,5), li1)
       [1, 2, 3]
    >>>removed((4,5), li1, only_duplicates=True)
       [1, 2, 3, 4, 5]

    # remove all duplicates by passing original_list also to `items`.:
    >>>removed(li1, li1, only_duplicates=True)
      [1, 2, 3, 4, 5]

    # inplace:
    >>>removed((4,5), li1, only_duplicates=True, inplace=True)
    >>>li1
        [1, 2, 3, 4, 5]

    >>>li2 =['abc', 'def', 'def', 'ghi', 'ghi']
    >>>removed(('def', 'ghi'), li2, only_duplicates=True, inplace=True)
    >>>li2
        ['abc', 'def', 'ghi']
"""

आपको इस बारे में स्पष्ट होना चाहिए कि आप वास्तव में क्या करना चाहते हैं, किसी मौजूदा सूची को संशोधित करें या लापता वस्तुओं के साथ एक नई सूची बनाएं। यह महत्वपूर्ण है कि यदि आपके पास मौजूदा सूची की ओर इशारा करते हुए एक दूसरा संदर्भ है तो यह अंतर करना महत्वपूर्ण है। यदि आपके पास, उदाहरण के लिए ...

li1 = [1, 2, 3, 4, 4, 5, 5]
li2 = li1
# then rebind li1 to the new list without the value 4
li1 = removed(4, li1)
# you end up with two separate lists where li2 is still pointing to the 
# original
li2
# [1, 2, 3, 4, 4, 5, 5]
li1
# [1, 2, 3, 5, 5]

यह वह व्यवहार हो सकता है जो आप चाहते हैं या नहीं।


1

आप उपयोग कर सकते हैं filterfalse से समारोह itertools मॉड्यूल

उदाहरण

import random
from itertools import filterfalse

random.seed(42)

data = [random.randrange(5) for _ in range(10)]
clean = [*filterfalse(lambda i: i == 0, data)]
print(f"Remove 0s\n{data=}\n{clean=}\n")


clean = [*filterfalse(lambda i: i in (0, 1), data)]
print(f"Remove 0s and 1s\n{data=}\n{clean=}")

आउटपुट:

Remove 0s
data=[0, 0, 2, 1, 1, 1, 0, 4, 0, 4]
clean=[2, 1, 1, 1, 4, 4]

Remove 0s and 1s
data=[0, 0, 2, 1, 1, 1, 0, 4, 0, 4]
clean=[2, 4, 4]

0

लेकिन क्या होगा अगर मैं उन वस्तुओं के सूचकांकों को नहीं जानता जिन्हें मैं हटाना चाहता हूं?

मुझे ठीक से समझ नहीं आ रहा है कि आपको पसंद क्यों नहीं है। एक मान उपयोग के लिए पहला सूचकांक प्राप्त करने के लिए।

ind=item_list.index('item')

फिर संबंधित मान निकालें:

del item_list.pop[ind]

.index (मान) को मान की पहली घटना मिलती है, और .remove (मान) मूल्य की पहली घटना को हटा देता है


यदि आपको परिणाम मान की आवश्यकता नहीं है, तो del item_list[ind]इसके बजाय का उपयोग करने पर विचार करें pop।
— कोजिरो

-1

आप इसका उपयोग कर सकते हैं -

मान लीजिए हमारे पास एक सूची है, l = [1,2,3,4,5]

हम पिछले दो आइटम को एक स्टेटमेंट में डिलीट करना चाहते हैं

del l[3:]

हम उत्पादन:

l = [1,2,3]

इसे सरल रखें

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.