2016-01-25 5 views
18

क्या फ़िल्टर फ़िल्टर से डुप्लीकेट फ़िल्टर करने के लिए पाइथन में सूची समझ का उपयोग करने का कोई तरीका है?सूची समझों का उपयोग कर सूची में आसन्न डुप्लिकेट तत्वों को कैसे हटाया जाए?

>>> xs = [1,2,2,3] 
>>> print added.reAdj(xs) 
[1,2,3] 

एसई के माध्यम से एक खोज एक समान लेकिन थोड़ा अलग सवाल पूछने एक earlier inquiry पता चला: सभी डुप्लिकेट एक सूची, लेकिन स्पष्ट रूप से नहीं से निकाला जा सकता है कि क्या

यहाँ मैं क्या मतलब का एक उदाहरण है सूची समझने वाले समाधानों के लिए पूछना। सूची समझ का उपयोग करने के लिए प्रेरणा विशेष रूप से their advantages over traditional for loops की पहचान का पालन करती है।

result = [] 
most_recent_elem = None 
for e in xs: 
    if e != most_recent_elem: 
     result.append(e) 
     most_recent_elem = e 

set() सुझाव है, कि गैर आसन्न डुप्लिकेट में काम निकाल दिए जाते हैं पूरा करने में विफल है, जबकि पाश प्रभावी लेकिन वर्बोज़ है: उपयोगकर्ताओं को इस तरह के रूप सेट() फ़ंक्शन या मानक पाशन के उपयोग का सुझाव दिया।

यह एक सूची समझ में अगले तत्व को सुरक्षित रूप से संदर्भित करने का माध्यम लगता है जैसा कि आवश्यक है।

[x for x in xs if x != **x.next()**] 

कोई विचार?

+0

यह और भी मतलब यह है '[1,2,2,2,2 , 3,3,3,4,5,6,6] -> [1,2,3,4,5,6] '? –

+0

@IronFist, आप सही ढंग से समझते हैं। वांछित परिणाम है। –

+0

@Achampion। लिंक के लिए धन्यवाद, लेकिन जहां तक ​​मैं कह सकता हूं, पोस्टर विशेष रूप से सूची समझ से जुड़े उत्तर के लिए नहीं पूछता है। मेरे मूल प्रश्न पोस्ट में एक लूप समाधान शामिल था। –

उत्तर

17

आप @AChampion ने सुझाव दिया समाधान के साथ list comprehension और enumerate इस्तेमाल कर सकते हैं:

xs = [1,2,2,2,1,1] 
In [115]: [n for i, n in enumerate(xs) if i==0 or n != xs[i-1]] 
Out[115]: [1, 2, 1] 

उस सूची में समझ वापसी आइटम अगर यह पहले या निम्न के लिए है अगर यह पिछले के बराबर नहीं है। यह if कथन के आलसी मूल्यांकन के कारण काम करेगा।

+0

@AntonProtopopov पर उलझन में डाल दिया। जब आप प्रगति करते हैं तो कृपया अपडेट करें। यह दुर्भाग्यपूर्ण है कि स्टीफन पोचमन लाया गया मामला काम नहीं करता है क्योंकि आपका समाधान अन्यथा बहुत ही सुरुचिपूर्ण आईएमओ है। –

+0

@ एंटोनप्रोटोपोव - ** कृपया **, कृपया, कृपया अपने उत्तर में एशैम्पियन के सुझाए गए फ़िक्स को शामिल करें। यह 'itertools' में कुछ अपरिवर्तनीय फ़ंक्शन के लिए एक अविश्वसनीय कॉल से इतना बेहतर है जिसका दस्तावेज़ बदले में अचूक है। –

+5

@ डेविड हैमेन 'ग्रुपबी' आसान और पूरी तरह से ठीक है, आपको इसे अपनी कमी के लिए दोष नहीं देना चाहिए। –

30

आप itertools.groupby उपयोग कर सकते हैं:

>>> import itertools 
>>> [key for key, grp in itertools.groupby([1, 2, 2, 3])] 
[1, 2, 3] 

itertools.groupby पुनरावर्तक देता है। इसे पुन: स्थापित करके, आपको एक कुंजी, समूह जोड़े मिलेंगे। (key कोई आइटम नहीं होगा यदि key फ़ंक्शन निर्दिष्ट है, अन्यथा key फ़ंक्शन का वापसी मूल्य)। group पुनरावर्तक जो key समारोह को लागू करने के आधार पर वर्गीकृत किया पैदावार आइटम जाएगा (यदि निर्दिष्ट नहीं है, एक ही मान समूहीकृत किया जाएगा)

>>> import itertools 
>>> it = itertools.groupby([1, 2, 2, 3]) 
>>> it 
<itertools.groupby object at 0x7feec0863048> 
>>> for key, grp in it: 
...  print(key) 
...  print(grp) 
... 
1 
<itertools._grouper object at 0x7feec0828ac8> 
2 
<itertools._grouper object at 0x7feec0828b00> 
3 
<itertools._grouper object at 0x7feec0828ac8> 
>>> it = itertools.groupby([1, 2, 2, 3]) 
>>> for key, grp in it: 
...  print(list(grp)) 
... 
[1] 
[2, 2] 
[3] 

समाधान ऊपर, मैं केवल key इस्तेमाल किया क्योंकि सवाल परवाह नहीं करता कि कितने आइटम निकट हैं।

+1

सॉर्ट किए गए इनपुट के बिना इस्तेमाल किए गए 'groupby' को देखना बहुत अजीब है, लेकिन मुझे लगता है कि यह वास्तव में इस विशेष उपयोग मामले में उपयुक्त है। – wim

+0

वही यहाँ मुझे पहले – AChampion

4

आप एक कम वर्बोज़ पाश समाधान इस्तेमाल कर सकते हैं:

>>> result = xs[:1] 
>>> for e in xs: 
     if e != result[-1]: 
      result.append(e) 

या:

>>> result = [] 
>>> for e in xs: 
     if e not in result[-1:]: 
      result.append(e) 
5

(zip_longest के साथ) itertools व्यंजनों से जोड़ो में उपयोग करने से आप अगले तत्व जाँच के लिए एक आसान तरीका देता है:

import itertools as it 

def pairwise(iterable): 
    a, b = it.tee(iterable) 
    next(b, None) 
    return it.zip_longest(a, b, fillvalue=object()) # izip_longest for Py2 

>>> xs = [1,2,2,3] 
>>> [x for x, y in pairwise(xs) if x != y] 
[1, 2, 3] 
>>> xs = [1,2,2,2,2,3,3,3,4,5,6,6] 
>>> [x for x, y in pairwise(xs) if x != y] 
[1, 2, 3, 4, 5, 6] 
+2

थोड़ा नाइटपिक: यह पिछला 'कोई नहीं' मान हटा देता है। –

+0

नोट किया गया: लेकिन इनट्स की सूची के साथ कोई समस्या नहीं है। और 'zip_longest' को 'fillvalue' जोड़ने के साथ बचाया जा सकता है, निश्चित! – AChampion

3

कैसे इस बारे में:

>>> l = [1,1,2,3,4,4,4,4,5,6,3,3,5,5,7,8,8,8,9,1,2,3,3,3,10,10] 
>>> 
>>> o = [] 
>>> p = None 
>>> for n in l: 
     if n == p: 
      continue 
     o.append(n) 
     p = n  

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

जाहिर है, इसके बाद के संस्करण समाधान, ओपी की तुलना में अधिक वर्बोज़ है इसलिए यहाँ itertools मॉड्यूल से कि zip_longest उपयोग का एक विकल्प है:

>>> l 
[1, 1, 2, 3, 4, 4, 4, 4, 5, 6, 3, 3, 5, 5, 7, 8, 8, 8, 9, 1, 2, 3, 3, 3, 10, 10] 
>>> from itertools import zip_longest 
>>> o = [p for p,n in zip_longest(l,l[1:]) if p != n] #By default fillvalue=None 
>>> o 
[1, 2, 3, 4, 5, 6, 3, 5, 7, 8, 9, 1, 2, 3, 10] 
+1

यह काम करता है लेकिन ओपी के रूप में यह वही तर्क है, थोड़ा और वर्बोज़ को छोड़कर। –

+0

@AlexanderHuszagh .. हाँ ... मैं उस बिंदु के बारे में भूल गया * verbosity * –

+1

अद्यतन .. 'zip_longest' का उपयोग कर –

संबंधित मुद्दे