2009-10-08 4 views
88

का उपयोग करके सूची में मूल्यों को बदलें, मेरे पास एक सूची है जहां मैं मूल्यों को प्रतिस्थापित करना चाहता हूं, जहां कोई शर्त() सत्य लौटाती है।पायथन

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 

उदाहरण के लिए, अगर हालत चेकों bool (मद% 2) लौटना चाहिए:

[None, 1, None, 3, None, 5, None, 7, None, 9, None] 

यह करने के लिए सबसे कारगर तरीका क्या है?

+0

itertools मॉड्यूल का उपयोग करें, यह सबसे कुशल है। – LtWorf

+1

'इन-प्लेस' प्रतिस्थापन तुलना के लिए, इस पर एक नज़र डालें [उत्तर] (http://stackoverflow.com/a/24203748/307454) – lifebalance

उत्तर

130

बिल्ड एक सूची समझ के साथ एक नई सूची:

new_items = [x if x % 2 else None for x in items] 

आप मूल सूची में जगह अगर आप चाहते हैं संशोधित कर सकते हैं, लेकिन यह वास्तव में समय की बचत नहीं करता है:

items = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
for index, item in enumerate(items): 
    if not (item % 2): 
     items[index] = None 

यहां (पायथन 3.6.3) गैर-टाइम्सव का प्रदर्शन करने वाले समय हैं:

In [1]: %%timeit 
    ...: items = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
    ...: for index, item in enumerate(items): 
    ...:  if not (item % 2): 
    ...:   items[index] = None 
    ...: 
1.06 µs ± 33.7 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) 

In [2]: %%timeit 
    ...: items = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
    ...: new_items = [x if x % 2 else None for x in items] 
    ...: 
891 ns ± 13.6 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) 

और अजगर 2.7.6 समय:

In [1]: %%timeit 
    ...: items = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
    ...: for index, item in enumerate(items): 
    ...:  if not (item % 2): 
    ...:   items[index] = None 
    ...: 
1000000 loops, best of 3: 1.27 µs per loop 
In [2]: %%timeit 
    ...: items = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
    ...: new_items = [x if x % 2 else None for x in items] 
    ...: 
1000000 loops, best of 3: 1.14 µs per loop 
+2

क्या यह सबसे कुशल है? गणना नहीं करता है कि एक इटरेटर बनाने और एक ट्यूपल बनाने के लिए, ऊपर की ओर जोड़ना है? पाइथन सरणीसूची में सूचियां हैं, जो आपको निरंतर समय तक पहुंच प्रदान करती हैं? – geowa4

+0

मुझे लगता है, और मैं गलत हो सकता हूं, कि वह मूल स्थान को संशोधित करने के बजाय सूची की प्रतिलिपि के लिए वापस लौटाया गया था। लेकिन फिर भी, जब जगह में संशोधन की अनुमति है तो कुशल समाधान की पेशकश के लिए +1। –

+0

अगर मैं मूल स्थान को संशोधित करना चाहता था, तो क्या Itertools से imap का उपयोग करना भी संभव नहीं होगा? –

2
>>> L = range (11) 
>>> [ x if x%2 == 1 else None for x in L ] 
[None, 1, None, 3, None, 5, None, 7, None, 9, None] 
53
ls = [x if (condition) else None for x in ls] 
10

एक तरफ सवाल एक टिप्पणी में ओपी ने पूछा, यानी पर riffing:

क्या हुआ अगर मैं एक जनरेटर है कि पैदावार था सूची के बजाय श्रेणी (11) के मान। जनरेटर में मानों को प्रतिस्थापित करना संभव होगा?

ज़रूर, यह trivially आसान है ...:

def replaceiniter(it, predicate, replacement=None): 
    for item in it: 
    if predicate(item): yield replacement 
    else: yield item 

बस किसी भी iterable पहले आर्ग, तय करने के लिए विधेय के रूप में (एक जनरेटर बुला का परिणाम सहित) पारित करता है, तो एक मूल्य बदला जाना चाहिए दूसरे तर्क के रूप में, और 'एआर चीर चलो।

उदाहरण के लिए:

>>> list(replaceiniter(xrange(11), lambda x: x%2)) 
[0, None, 2, None, 4, None, 6, None, 8, None, 10] 
+0

+1 हेहे ... मैं सीखना चाहता हूं कि यह" एक "लाइन निफ्टी पायथन समाधान कैसे लिखना है ... संकेत दें – gath

+0

@gath, मुझे आपका प्रश्न नहीं पता - टिप्पणियां हैं बहुत सीमित है इसलिए आपको एक नया प्रश्न खोलना चाहिए ताकि आप जो भी खोज रहे हैं उसे विस्तार और स्पष्टीकरण दे सकें ... –

8

यहाँ एक और तरीका है:

>>> L = range (11) 
>>> map(lambda x: x if x%2 else None, L) 
[None, 1, None, 3, None, 5, None, 7, None, 9, None] 
+1

+1 और लोग इस लाइन को निफ्टी पायथन कोड कैसे सीखते हैं ... संकेत – gath

+5

@gath: डॉन ' हर उद्देश्य के लिए एक लाइनर लिखने की इच्छा नहीं है। कभी-कभी, वे पठनीयता या प्रदर्शन में वृद्धि करते हैं, लेकिन अक्सर वे नहीं करते हैं। संकेतों के रूप में: पाइथन ऑफर्स, विशेष रूप से सूची (और पायथन 3 के लिए भी निर्देश) की समझ, टर्नरी ऑपरेटर, अज्ञात (लैम्ब्डा) फ़ंक्शन, और मानचित्र, ज़िप, फ़िल्टर, कम इत्यादि जैसे कार्यों को जानने के लिए – balpha

2

यह मदद कर सकता है ...

test_list = [5, 8] 
test_list[0] = None 
print test_list 
#prints [None, 8] 
+1

कैन आप कुछ बताते हैं कि आपको क्यों लगता है कि इससे मदद मिल सकती है? –

+0

@ टी-हेरॉन इसे – Emil

+0

के लिए पूछे जाने वाले प्रश्न को पूरा करने के लिए संशोधित किया जा सकता है यदि इसे * संशोधित * होने की आवश्यकता है, तो यह पूछे जाने वाले प्रश्न का उत्तर नहीं है। कृपया या तो आवश्यक संशोधन स्वयं करें (या समझाएं), या उत्तर हटाएं। –

0

मामले में आप जगह में मान बदलना चाहते हैं, आप कर सकते हैं अपनी मूल सूची को सूची से मूल्यों के साथ अपडेट करें comprehensi मूल के पूरे टुकड़े को सौंपकर।

data = [*range(11)] # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
id_before = id(data) 
data[:] = [x if x % 2 else None for x in data] 
data 
# Out: [None, 1, None, 3, None, 5, None, 7, None, 9, None] 
id_before == id(data) # check if list is still the same 
# Out: True 

आप मूल सूची की ओर इशारा करते से अधिक नाम हो, उदाहरण के लिए आप data2=data सूची बदलने से पहले लिखा था और आप data को निर्दिष्ट करने के लिए टुकड़ा अंकन को छोड़, data को नव निर्मित बात करने के लिए rebind होगा सूची data2 अभी भी मूल अपरिवर्तित सूची को इंगित करती है।

data = [*range(11)] # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
data2 = data 
id_before = id(data) 
data = [x if x % 2 else None for x in data] # no [:] here 
data 
# Out: [None, 1, None, 3, None, 5, None, 7, None, 9, None] 
id_before == id(data) # check if list is still the same 
# Out: False 
data2 
# Out: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 

नोट: यह आम तौर पर अन्य के ऊपर एक पसंद करते हैं (जगह में सूची को बदलने या नहीं), लेकिन व्यवहार आप के बारे में पता होना चाहिए के लिए कोई अनुशंसा नहीं है।