सूची में तत्वों को खोजना और बदलना


273

मुझे एक सूची के माध्यम से खोजना है और एक तत्व की सभी घटनाओं को दूसरे के साथ बदलना है। अब तक कोड में मेरे प्रयास मुझे कहीं नहीं मिल रहे हैं, ऐसा करने का सबसे अच्छा तरीका क्या है?

उदाहरण के लिए, मान लें कि मेरी सूची में निम्नलिखित पूर्णांक हैं

>>> a = [1,2,3,4,5,1,2,3,4,5,1]

और मुझे संख्या 1 की सभी घटनाओं को मूल्य 10 के साथ बदलने की आवश्यकता है, इसलिए आउटपुट की मुझे आवश्यकता है

>>> a = [10, 2, 3, 4, 5, 10, 2, 3, 4, 5, 10]

इस प्रकार मेरा लक्ष्य नंबर 1 के सभी उदाहरणों को 10 नंबर से बदलना है।


11
यह किस तरह से है?
outis

का डुप्लीकेट stackoverflow.com/q/1540049/819417
Cees Timmerman

जवाबों:


250
>>> a= [1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1]
>>> for n, i in enumerate(a):
...   if i == 1:
...      a[n] = 10
...
>>> a
[10, 2, 3, 4, 5, 10, 2, 3, 4, 5, 10]

15
यह एक बुरा और बहुत ही अन-पाइथोनिक घोल है। सूची समझ का उपयोग करने पर विचार करें।
AdHominem

203
यह एक अन-पाइथोनिक विलयन है तो ठीक है। सूची समझ का उपयोग करने पर विचार करें।
जीन-फ्रांकोइस कॉर्बेट

सूची समझ का उपयोग करने पर विचार करें, जैसे नीचे @outis द्वारा किया गया है!
एमके

6
हालांकि यह सूची समझ से बेहतर प्रदर्शन करता है? यह नई सूची बनाने के बजाय इन-प्लेस अपडेट करता है।
neverendingqs

@neverendingqs: नहीं। इंटरप्रेटर ओवरहेड ऑपरेशन पर हावी है, और इसकी समझ कम है। समझदारी थोड़ा बेहतर प्रदर्शन करती है, विशेष रूप से प्रतिस्थापन स्थिति से गुजरने वाले तत्वों के उच्च अनुपात के साथ। कुछ समय है: ideone.com/ZrCy6z
user2357112

517

एक सूची समझ और टर्नरी ऑपरेटर का उपयोग करने का प्रयास करें ।

>>> a=[1,2,3,1,3,2,1,1]
>>> [4 if x==1 else x for x in a]
[4, 2, 3, 4, 3, 2, 4, 4]

9
लेकिन यह aसही नहीं बदलता है ? मुझे लगता है कि ओपी aबदलना चाहता था
दुला

10
@ क्या आप एक = [४ अगर x == १ और x के लिए x में] कर सकते हैं, तो यह एक असर करेगा
अलेख्य वेमवरपु ११'१६ को do:

@ डूला: सवाल अस्पष्ट है कि क्या aम्यूट करना चाहिए, लेकिन (जैसा कि अलेखा दिखाता है) किसी सूची को समझने के दौरान किसी भी मामले को संभालने के लिए यह तुच्छ है।
16

34
यदि आप म्यूट करना चाहते हैं aतो आपको करना चाहिए a[:] = [4 if x==1 else x for x in a](पूरी सूची स्लाइस पर ध्यान दें)। बस करने से मूल से अलग (पहचान) के साथ a =एक नई सूची aid()
बनेगी

39

सूची समझ अच्छी तरह से काम करती है, और एन्यूमरेट के माध्यम से लूपिंग आपको कुछ मेमोरी (b / c ऑपरेशन के अनिवार्य रूप से जगह में होने के कारण) बचा सकता है।

कार्यात्मक प्रोग्रामिंग भी है। मानचित्र का उपयोग देखें :

>>> a = [1,2,3,2,3,4,3,5,6,6,5,4,5,4,3,4,3,2,1]
>>> map(lambda x: x if x != 4 else 'sss', a)
[1, 2, 3, 2, 3, 'sss', 3, 5, 6, 6, 5, 'sss', 5, 'sss', 3, 'sss', 3, 2, 1]

17
+1। यह बहुत बुरा है lambdaऔर mapइसे अप्राकृतिक माना जाता है।
outis

4
मुझे यकीन नहीं है कि लैम्ब्डा या मानचित्र स्वाभाविक रूप से अप्रसांगिक है, लेकिन मैं सहमत हूं कि एक सूची की समझ क्लीनर है और संयोजन में उन दोनों का उपयोग करने की तुलना में अधिक पठनीय है।
डैमज़ाम

7
मैं उन्हें खुद को अपाहिज नहीं मानता, लेकिन कई लोग करते हैं, जिसमें गुइडो वैन रोसुम ( artima.com/weblogs/viewpost.jsp?thread=98196 ) शामिल हैं। यह उन सांप्रदायिक चीजों में से एक है।
outis

35

यदि आपके पास प्रतिस्थापित करने के लिए कई मान हैं, तो आप एक शब्दकोश का उपयोग भी कर सकते हैं:

a = [1, 2, 3, 4, 1, 5, 3, 2, 6, 1, 1]
dic = {1:10, 2:20, 3:'foo'}

print([dic.get(n, n) for n in a])

> [10, 20, 'foo', 4, 10, 5, 'foo', 20, 6, 10, 10]

1
अगर nयह नहीं मिला है तो क्या यह एक त्रुटि नहीं है dic?
नील ए।

3
@ user2914540 मैंने आपके उत्तर को थोड़ा सुधार दिया है, अगर nयह नहीं मिला तो काम करता है। मुझे आशा है कि आपको कोई आपत्ति नहीं है। आपका try/exceptसमाधान अच्छा नहीं था।
jrjc

अरे हाँ, यह बेहतर है।
रोसौसेरियो

1
@jrjc @roipoussiere इन-प्लेस प्रतिस्थापन के लिए, try-exceptकम से कम 50% तेज है! इस उत्तर
जीवनरक्षकता

4
if n in dic.keys()खराब प्रदर्शन-वार है। का प्रयोग करें if n in dicया dic.get(n,n)(डिफ़ॉल्ट मान)
जीन फ़्राँस्वा Fabre

12
>>> a=[1,2,3,4,5,1,2,3,4,5,1]
>>> item_to_replace = 1
>>> replacement_value = 6
>>> indices_to_replace = [i for i,x in enumerate(a) if x==item_to_replace]
>>> indices_to_replace
[0, 5, 10]
>>> for i in indices_to_replace:
...     a[i] = replacement_value
... 
>>> a
[6, 2, 3, 4, 5, 6, 2, 3, 4, 5, 6]
>>> 

मध्यम तेज़ लेकिन बहुत समझदार विधि। कृपया मेरे उत्तर में समय देखें।
dawg

10
a = [1,2,3,4,5,1,2,3,4,5,1,12]
for i in range (len(a)):
    if a[i]==2:
        a[i]=123

आप लूप के लिए या उसके लिए उपयोग कर सकते हैं; हालाँकि, यदि आप बिल्ड एनुमरेट फ़ंक्शन को जानते हैं, तो एन्यूमरेट का उपयोग करने की अनुशंसा की जाती है। 1


1
यह एकमात्र ऐसा समझदार (पठनीय) तरीका है जब आपको सूची आइटम पर अधिक जटिल संचालन करने की आवश्यकता होती है। उदाहरण के लिए, यदि प्रत्येक सूची आइटम एक लंबी स्ट्रिंग है, जिसे किसी प्रकार की खोज और प्रतिस्थापन की आवश्यकता होती है।
नॉट वाक् 2

8

सभी आसानी से प्रतिस्थापित करने के लिए 1साथ 10में a = [1,2,3,4,5,1,2,3,4,5,1]एक के बाद एक लाइन लैम्ब्डा + मानचित्र संयोजन इस्तेमाल कर सकते हैं, और 'देखो, मा, कोई अगर या Fors!' :

# This substitutes all '1' with '10' in list 'a' and places result in list 'c':

c = list(map(lambda b: b.replace("1","10"), a))


अब तक की सबसे धीमी विधि। आप lambdaप्रत्येक सूची तत्व पर कॉल कर रहे हैं ...
dawg

4

निम्नलिखित पायथन 2.x में एक बहुत ही सीधी विधि है

 a = [1,2,3,4,5,1,2,3,4,5,1]        #Replacing every 1 with 10
 for i in xrange(len(a)):
   if a[i] == 1:
     a[i] = 10  
 print a

यह तरीका काम करता है। टिप्पणियों का स्वागत है। आशा करता हूँ की ये काम करेगा :)

यह भी समझने की कोशिश करें कि आउटिस और डैमज़म के समाधान कैसे काम करते हैं। सूची संकुचन और लैम्ब्डा फ़ंक्शन उपयोगी उपकरण हैं।


3

मुझे पता है कि यह एक बहुत पुराना सवाल है और इसे करने के कई तरीके हैं। मैंने जो सरल पाया वह numpyपैकेज का उपयोग कर रहा है ।

import numpy

arr = numpy.asarray([1, 6, 1, 9, 8])
arr[ arr == 8 ] = 0 # change all occurrences of 8 by 0
print(arr)

3

मेरा usecase Noneकुछ डिफ़ॉल्ट मान के साथ बदल रहा था ।

मैं इस समस्या के लिए समयबद्ध दृष्टिकोण यहां प्रस्तुत कर रहा हूं, जिसमें @kxr - का उपयोग करके शामिल है str.count

Python 3.8.1 के साथ ipython में टेस्ट कोड:

def rep1(lst, replacer = 0):
    ''' List comprehension, new list '''

    return [item if item is not None else replacer for item in lst]


def rep2(lst, replacer = 0):
    ''' List comprehension, in-place '''    
    lst[:] =  [item if item is not None else replacer for item in lst]

    return lst


def rep3(lst, replacer = 0):
    ''' enumerate() with comparison - in-place '''
    for idx, item in enumerate(lst):
        if item is None:
            lst[idx] = replacer

    return lst


def rep4(lst, replacer = 0):
    ''' Using str.index + Exception, in-place '''

    idx = -1
    # none_amount = lst.count(None)
    while True:
        try:
            idx = lst.index(None, idx+1)
        except ValueError:
            break
        else:
            lst[idx] = replacer

    return lst


def rep5(lst, replacer = 0):
    ''' Using str.index + str.count, in-place '''

    idx = -1
    for _ in range(lst.count(None)):
        idx = lst.index(None, idx+1)
        lst[idx] = replacer

    return lst


def rep6(lst, replacer = 0):
    ''' Using map, return map iterator '''

    return map(lambda item: item if item is not None else replacer, lst)


def rep7(lst, replacer = 0):
    ''' Using map, return new list '''

    return list(map(lambda item: item if item is not None else replacer, lst))


lst = [5]*10**6
# lst = [None]*10**6

%timeit rep1(lst)    
%timeit rep2(lst)    
%timeit rep3(lst)    
%timeit rep4(lst)    
%timeit rep5(lst)    
%timeit rep6(lst)    
%timeit rep7(lst)    

मुझे मिला:

26.3 ms ± 163 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
29.3 ms ± 206 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
33.8 ms ± 191 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
11.9 ms ± 37.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
11.9 ms ± 60.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
260 ns ± 1.84 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
56.5 ms ± 204 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

आंतरिक str.indexका उपयोग करना वास्तव में किसी भी मैनुअल तुलना की तुलना में तेज है।

मुझे नहीं पता था कि परीक्षण 4 में अपवाद का उपयोग करने से अधिक श्रमसाध्य होगा str.count, तो अंतर नगण्य लगता है।

ध्यान दें कि map()(परीक्षण 6) एक पुनरावृत्ति देता है और वास्तविक सूची नहीं, इस प्रकार 7 का परीक्षण करें।


3

अन्य सूचियों list.index()में प्रस्तुत एकल चरण पुनरावृत्ति विधियों की तुलना में लंबी सूचियों और दुर्लभ घटनाओं के बारे में इसका उपयोग 3x तेज होता है।

def list_replace(lst, old=1, new=10):
    """replace list elements (inplace)"""
    i = -1
    try:
        while 1:
            i = lst.index(old, i + 1)
            lst[i] = new
    except ValueError:
        pass

यह सबसे तेज़ तरीका है जो मैंने पाया है। कृपया मेरे उत्तर में समय देखें। महान!
dawg

2

आप बस अजगर में सूची समझ का उपयोग कर सकते हैं:

def replace_element(YOUR_LIST, set_to=NEW_VALUE):
    return [i
            if SOME_CONDITION
            else NEW_VALUE
            for i in YOUR_LIST]

आपके मामले के लिए, जहां आप 1 की सभी घटनाओं को 10 के साथ बदलना चाहते हैं, कोड स्निपेट इस तरह होगा:

def replace_element(YOUR_LIST, set_to=10):
    return [i
            if i != 1  # keeps all elements not equal to one
            else set_to  # replaces 1 with 10
            for i in YOUR_LIST]

3
हालांकि यह कोड स्निपेट प्रश्न को हल कर सकता है, जिसमें स्पष्टीकरण सहित वास्तव में आपकी पोस्ट की गुणवत्ता में सुधार करने में मदद करता है। याद रखें कि आप भविष्य में पाठकों के लिए प्रश्न का उत्तर दे रहे हैं, और उन लोगों को आपके कोड सुझाव के कारणों का पता नहीं चल सकता है। कृपया व्याख्यात्मक टिप्पणियों के साथ अपने कोड को भीड़ने की कोशिश न करें, इससे कोड और स्पष्टीकरण दोनों की पठनीयता कम हो जाती है!
18'18

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