2009-09-28 19 views
5

Howdy, codeboys और codegirls!दो या दो से अधिक सूचियों में मूल्यांकन

मुझे लगता है कि यह आसान समाधान के साथ एक साधारण समस्या में आया है। लेकिन एक पाइथन neophyte होने के नाते मुझे लगता है कि कहीं बेहतर दृष्टिकोण है।

कहें कि आपके पास मिश्रित तारों की एक सूची है। बोरी में दो मूल प्रकार के तार होते हैं - उनमें से "=" (= = आलू) और बिना (लेडी जेन) वाले होते हैं। आपको दो सूचियों में सॉर्ट करने की आवश्यकता है।

for arg in arguments: 
    if '=' in arg: 
     equal.append(arg) 
    else: 
     plain.append(arg) 

क्या कोई अन्य, इसे में और अधिक सुरुचिपूर्ण रास्ता नहीं है:

स्पष्ट दृष्टिकोण के लिए है? कुछ ऐसा:

equal = [arg for arg in arguments if '=' in arg] 

लेकिन एकाधिक सूचियों में सॉर्ट करने के लिए?

और यदि आपके पास एक से अधिक प्रकार के डेटा हैं तो क्या होगा?

+3

मुझे लगता है कि आपका स्पष्ट दृष्टिकोण पूरी तरह से अच्छा है, और कई उत्तरों की तुलना में अधिक पढ़ा जा सकता है अब तक सुझाव दिया! –

+0

दरअसल, मुझे लगता है कि सूची की समझ पाइथन की सबसे खूबसूरत विशेषताओं में से एक है जिसे मैं लगातार सी ++ लिखते समय लालसा करता हूं! उनमें से 2 उत्तर – Steg

उत्तर

4

for arg in arguments: 
    lst = equal if '=' in arg else plain 
    lst.append(arg) 

या (पवित्र बदसूरत)

for arg in arguments: 
    (equal if '=' in arg else plain).append(arg) 

प्रयास करें एक तीसरा विकल्प: एक वर्ग जो append() प्रदान करता है और जो कई सूचियों में सॉर्ट बनाएँ।

+0

में से किसी भी उत्तर से बहुत अच्छे हैं, मुझे फॉर्म 'सूची = (' = 'arg में) और बराबर या सादे' के रूप में अधिक पठनीय लगता है। – giorgian

+0

आप अंतर्निहित – SilentGhost

+0

शेडिंग कर रहे हैं मुझे लगता है कि "ए if cond else b" बहुत पठनीय अंग्रेजी है; मैं सिर्फ एक पंक्ति में बहुत ज्यादा नहीं रखना पसंद करता हूं। –

4

आप इस के लिए itertools.groupby() उपयोग कर सकते हैं: हालांकि यह सबसे कारगर समाधान नहीं है

import itertools 
f = lambda x: '=' in x 
groups = itertools.groupby(sorted(data, key=f), key=f) 
for k, g in groups: 
    print k, list(g) 
+3

मैंने सोचा कि उसने सुरुचिपूर्ण – Steg

+0

के लिए पूछा है सॉर्टिंग इसे nlog (n) बनाता है जबकि एक सरल ओ (एन) समाधान मौजूद है। –

1

एक और दृष्टिकोण, filter समारोह का प्रयोग है।
उदाहरण:

>>> l = ['a=s','aa','bb','=', 'a+b'] 
>>> l2 = filter(lambda s: '=' in s, l) 
>>> l3 = filter(lambda s: '+' in s, l) 
>>> l2 
['a=s', '='] 
>>> l3 
['a+b'] 
2
def which_list(s): 
    if "=" in s: 
     return 1 
    return 0 

lists = [[], []] 

for arg in arguments: 
    lists[which_list(arg)].append(arg) 

plain, equal = lists 

आप का डेटा है, तो which_list के लिए एक अगर खंड जोड़ने के लिए, और lists के लिए और अधिक खाली सूचियों आरंभ कर देगा।

+0

जो_सूची बहुत आसान हो सकती है - मेरा उत्तर देखें। अन्यथा, हमारे उत्तर बहुत करीब हैं। – PaulMcG

+0

वास्तव में, यह हो सकता है, लेकिन ओपी ने दो से अधिक संभावनाओं के मामले के बारे में पूछा, जिसे मैं प्रारंभिक डिजाइन में सौदा करना चाहता था। –

+0

उस स्थिति में, मुझे लगता है कि सूचियों का एक शब्दकोश स्पष्ट होगा। सूची सूचकांक व्यर्थ हैं। –

3

मैं सिर्फ दो सूची समझों के लिए जाऊंगा। हालांकि इसमें कुछ ओवरहेड (सूची में दो लूप) होते हैं, लेकिन इसके लिए उपयोग करने की तुलना में सूची समझ का उपयोग करने के लिए यह अधिक पाइथोनिक होता है। यह भी (मेरे दिमाग में) वास्तव में कूल चाल के सभी प्रकारों का उपयोग करने से कहीं अधिक पठनीय है, लेकिन कम लोगों को पता है।

1

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

def split_on_condition(source, condition): 
    ret = [],[] 
    for s in source: 
     ret[condition(s)].append(s) 
    return ret 

src = "z=1;q=2;lady jane;y=a;lucy in the sky".split(';') 

plain,equal = split_on_condition(src, lambda s:'=' in s) 
1

आपका दृष्टिकोण सबसे अच्छा है। केवल दो सूचियों में छंटनी के लिए यह उससे स्पष्ट नहीं हो सकता है। आप इसे एक एक लाइनर होना चाहते हैं, एक समारोह में यह संपुटित:

def classify(arguments): 
    equal, plain = [], [] 
    for arg in arguments: 
     if '=' in arg: 
      equal.append(arg) 
     else: 
      plain.append(arg) 
    return equal, plain 


equal, plain = classify(lst) 
2

मैं Edan का दृष्टिकोण है, उदा के लिए जाना होगा

equal = [arg for arg in arguments if '=' in arg] 
plain = [arg for arg in arguments if '=' not in arg] 
2

मैंने कहीं पढ़ा है कि यहां आपको लगता है कि अधिक दो पहचानकर्ता (संकेत और अंतरिक्ष के बराबर होती है) की तुलना में के लिए काम करेंगे एक समाधान में रुचि हो सकती।

निम्नलिखित समाधान केवल आपके कुछ भी आप मैच के लिए चाहते हैं के साथ uniques सेट अपडेट करने की आवश्यकता है, परिणाम कुंजी के रूप में पहचानकर्ता के साथ सूची का एक शब्दकोश में रखा जाता है।

uniques = set('= ') 
matches = dict((key, []) for key in uniques) 

for arg in args: 
    key = set(arg) & uniques 
    try: 
     matches[key.pop()].append(arg) 
    except KeyError: 
     # code to handle where arg does not contain = or ' '. 

अब उपरोक्त कोड मानता है कि आप केवल अपने arg में अपने पहचानकर्ता के लिए एक एकल मैच होगा। मैं आपके पास arg नहीं है जो इस 'John= equalspace' जैसा दिखता है। आपको यह भी सोचना होगा कि आप उन मामलों का इलाज कैसे करना चाहते हैं जो सेट में किसी भी चीज़ से मेल नहीं खाते हैं (KeyError होता है।)

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