2017-02-17 9 views
10

मैं जो दिखता हैमुझे किसी विशेष तत्व के साथ सूचियों की संख्या कैसे प्राप्त हो सकती है?

तरह
listOfLists = [ 
    ['a','b','c','d'], 
    ['a','b'], 
    ['a','c'], 
    ['c','c','c','c'] 
] 

मैं सूचियों जो एक विशेष तत्व है की संख्या की गणना करना चाहते सूचियों की एक सूची, की है। उदाहरण के लिए, मेरा आउटपुट

{'a':3,'b':2,'c':3,'d':1} 

जैसा कि आप देख सकते हैं, मुझे किसी तत्व की कुल गणना की आवश्यकता नहीं है। "c" के मामले में, हालांकि इसकी कुल गणना 5 है, आउटपुट 3 है क्योंकि यह केवल 3 सूचियों में होता है।

मैं गणना प्राप्त करने के लिए काउंटर का उपयोग कर रहा हूं। वही नीचे देखा जा सकता है।

line_count_tags = [] 
for lists in lists_of_lists: 
    s = set() 
    for element in lists: 
     s.add(t) 
    lines_count_tags.append(list(s)) 

count = Counter([count for counts in lines_count_tags for count in counts]) 

तो, जब मैं गिनती प्रिंट, मैं

{'a':3,'c':3,'b':2,'d':1} 

मैं वहाँ एक बेहतर तरीका है अपने लक्ष्य को पूरा करने के लिए है कि अगर जानना चाहते हैं मिलता है।

उत्तर

11

Counter का उपयोग करें और प्रत्येक सूची को एक सेट में कनवर्ट करें। - Counter को map ped listOfLists

>>> from collections import Counter 

>>> Counter(item for lst in listOfLists for item in set(lst)) 
Counter({'a': 3, 'b': 2, 'c': 3, 'd': 1}) 

आप कार्यात्मक प्रोग्रामिंग की तरह आप भी एक के chainset फ़ीड कर सकते हैं: ताकि आप एक ही सूची में डुप्लिकेट मानों गिनती नहीं है set प्रत्येक सूची से किसी भी डुप्लिकेट निकाल देंगे :

>>> from collections import Counter 
>>> from itertools import chain 

>>> Counter(chain.from_iterable(map(set, listOfLists))) 
Counter({'a': 3, 'b': 2, 'c': 3, 'd': 1}) 

जो पहले दृष्टिकोण के लिए पूरी तरह से बराबर है (शायद थोड़ा तेज़ होने के अलावा)।

9

मैं एक जनरेटर समझ में गिनती से पहले एक सेट के रूप में प्रत्येक सूची में बदल सकते हैं Counter के लिए पारित:

import collections 
print(collections.Counter(y for x in listOfLists for y in set(x))) 

परिणाम:

Counter({'a': 3, 'c': 3, 'b': 2, 'd': 1}) 

(कि व्यावहारिक रूप से आप क्या किया है, लेकिन इसके बाद के संस्करण कोड शॉर्ट्स बहुत सारे लूप और अस्थायी सूची निर्माण)

7

आप भी एक Counter बिना यह कर सकते हैं:

result = {} 
for lis in listOfLists: 
    for element in set(lis): 
     result[element] = result.get(element, 0) + 1 
print result # {'a': 3, 'c': 3, 'b': 2, 'd': 1} 

नहीं सबसे खूबसूरत है, लेकिन काफी तेज किया जाना चाहिए।

5

itertools.chain.from_iterable साथ Counter दृष्टिकोण पर एक शैलीगत अंतर के बारे में थोड़ी तरह

Counter(chain.from_iterable(map(set, listOfLists))) 

डेमो

>>> from itertools import chain 
>>> from collections import Counter 
>>> Counter(chain.from_iterable(map(set, listOfLists))) 
Counter({'a': 3, 'b': 2, 'c': 3, 'd': 1}) 

असहज बेंचमार्क

लग सकता है 10
%timeit Counter(item for lst in listOfLists for item in set(lst)) 
100000 loops, best of 3: 13.5 µs per loop 

%timeit Counter(chain.from_iterable(map(set, listOfLists))) 
100000 loops, best of 3: 12.4 µs per loop 
+0

मुझे सीपीथन 2.7.11 पर 'itertools.chain' (~ 40%!) का उपयोग करके बहुत तेजी से निष्पादन मिलता है। फिर भी, 'काउंटर' + 'itertools.chain 'प्रस्तुत किए गए' कच्चे 'विधि से 4 गुना धीमा निष्पादित करता है। – zwer

+1

@zwer एह, निर्भर करता है कि हम किस इनपुट आकार पर चर्चा कर रहे हैं। मेरे समाधान में अधिक ओवरहेड है, लेकिन यदि आप इनपुट आकार बढ़ाते हैं तो यह तेज़ होगा। यही कारण है कि बेंचमार्किंग सभी महत्वपूर्ण नहीं है :) – miradulo

+0

यह सच है कि, मैं अपने स्थान पर गति में काफी अंतर से आश्चर्यचकित था, मैं वास्तव में 'itertools' के लिए उपयोग नहीं किया जाता है, वास्तव में, बहुत कुछ भी - वे हैं आमतौर पर धीमी, लेकिन पसंद को पढ़ने में आसान: डी – zwer

3

बस set में कनवर्ट करें, itertools.chain.from_iterable का उपयोग करके फ़्लैटन करें और फिर Counter पर फ़ीड करें।

from collections import Counter 
from itertools import chain 

inp = [ 
    ['a','b','c','d'], 
    ['a','b'], 
    ['a','c'], 
    ['c','c','c','c'] 
] 


print(Counter(chain.from_iterable(map(set, inp)))) 
2

यह दृष्टिकोण सेट समझ का उपयोग कर listOfLists में अद्वितीय प्रविष्टियों की गणना करता है, और फिर समझ

A = {val for s in listOfLists for val in s} 
d = {i: sum(i in j for j in listOfLists) for i in A} 
print(d) # {'a': 3, 'c': 3, 'b': 2, 'd': 1} 

शब्दकोश का उपयोग कर मैं इसे एक छोटे से बदसूरत है मानता हूँ प्रत्येक सूची में घटनाओं में गिना जाता है, लेकिन यह एक संभव समाधान है (और शब्दकोश समझ का एक अच्छा उपयोग)।

listOfLists = [ 
    ['a','b','c','d'], 
    ['a','b'], 
    ['a','c'], 
    ['c','c','c','c'] 
    ] 

final = {} 
for lst in listOfLists: 
    for letter in lst: 
     if letter in final: 
      final[letter] += 1 
     else: 
      final[letter] = 1 

तो एक खाली शब्दकोश अंतिम बनाएं जिसका नाम: तुम भी सही शब्दकोश समझ

+0

आपके सेट 'ए' को फिर से सूची में डालने की कोई आवश्यकता नहीं है या सूची समझ के साथ सेट को फ़ीड करने की आवश्यकता नहीं है, एक पीढ़ी अभिव्यक्ति बेहतर है ... असल में आप 'ए' बना सकते हैं 'एक सेट समझ के रूप में भी – Copperfield

+0

@ कोपरफील्ड आपके सुझाव के लिए धन्यवाद। मैंने एक बदलाव किया है। – nbryans

2

यहाँ में A की गणना को ले जाकर इसे एक एकल लाइनर कर सकता है छोरों का उपयोग कर एक और संस्करण है। फिर प्रत्येक सूची के प्रत्येक पत्र के माध्यम से लूप। यदि कोई कुंजी एक कुंजी के रूप में अंतिम रूप में मौजूद नहीं है तो एक नई कुंजी और मान = 1 बनाएं। अन्यथा उस कुंजी के मान में 1 जोड़ें।

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

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