2016-10-25 10 views
5

मैं जैसे कि निम्न अजगर में नाम, की एक सूची है कहो , लेकिन मैं उन्हें हटाना नहीं चाहता हूं। इसके बजाय, प्रत्येक सूची के लिए जो इस सूची में एक से अधिक बार प्रकट होता है, मैं उस नाम पर एक प्रत्यय जोड़ना चाहता हूं, जहां प्रत्यय एन-वें समय नाम प्रकट हुआ है, जबकि सूची के क्रम को संरक्षित किया गया है। चूंकि सूची में 3 कार्ल्स हैं, इसलिए मैं उन्हें क्रमशः कार्ल_1, कार्ल_2 और कार्ल_3 के रूप में संदर्भित करना चाहता हूं। इस प्रकार तो इस मामले में वांछित आउटपुट है:लेबलिंग डुप्लिकेट

names = ['Alice','Bob_1','Carl_1','Dave','Bob_2','Earl','Carl_2','Frank','Carl_3']

मैं सूची के माध्यम से पाशन और प्रत्येक नाम को संशोधित करने, यदि वह निम्न कोड की तरह कुछ के साथ, संशोधित करने की जरूरत है, उदाहरण के लिए ऐसा कर सकते हैं।

def mark_duplicates(name_list): 
    output = [] 
    duplicates = {} 
    for name in name_list: 
     if name_list.count(name) = 1: 
      output.append(name) 
     else: 
      if name in duplicates: 
       duplicates['name'] += 1 
      else: 
       duplicates['name'] = 1 
      output.append(name + "_" + str(duplicates['name'])) 
    return output 

हालांकि इस काम का एक बहुत कुछ और है कि मुझे लगता है बहुत करना बहुत मुश्किल नहीं होना चाहिए कुछ के लिए कोड की लाइनों की एक बहुत कुछ है। क्या मैं जो करना चाहता हूं उसे पूरा करने का एक आसान तरीका है? उदाहरण के लिए, सूची समझ या इटरटोल या कुछ जैसे पैकेज जैसे कुछ का उपयोग करना?

+0

मुझे नहीं लगता कि एक उचित एक लाइन है आर, अगर आप यही चाहते हैं। वैसे भी, अगर इनपुट '[' ऐलिस ',' ऐलिस ',' ऐलिस_1 ',' ऐलिस_2 '] है, तो आप क्या प्राप्त करने की उम्मीद करते हैं? – zvone

+0

सैद्धांतिक रूप से उस प्रकार का इनपुट कभी नहीं होगा। यदि ऐसा होता है, तो मुझे लगता है कि मैं खराब हो जाऊंगा क्योंकि हमारी परिणामी सूची '[' ऐलिस_1 ',' ऐलिस_2 ',' ऐलिस_1 ',' ऐलिस_2 '] होगी। –

+0

कारण मैंने पूछा क्योंकि आप संभवतः '[' ऐलिस_1 ',' ऐलिस_2 ',' ऐलिस_3 ',' ऐलिस_4 '] के परिणाम चाहते थे' (मुझे नहीं पता कि यह क्या है)। इसके लिए एक अलग एल्गोरिदम की आवश्यकता होगी। – zvone

उत्तर

8

collections.Counter मदद कर सकते हैं बहीखाता थोड़ा कटौती:

In [106]: out = [] 

In [107]: fullcount = Counter(names) 

In [108]: nc = Counter() 

In [109]: for n in names: 
    ...:  nc[n] += 1 
    ...:  out.append(n if fullcount[n] == 1 else '{}_{}'.format(n, nc[n])) 
    ...: 

In [110]: out 
Out[110]: 
['Alice', 'Bob_1', 'Carl_1', 'Dave', 'Bob_2', 'Earl', 'Carl_2', 'Frank', 'Carl_3'] 
0

निम्न कोड के लिए आप क्या देख रहे हैं और comprehensions का उपयोग करता है क्या करना चाहिए:

def get_duplicates(names): 
    counts = { k: 0 for k in names } 
    output = [] 
    for name in names: 
     if count[name] == 0: 
      output.append(name) 
      counts[name] += 1 
     else: 
      output.append("{}_{}".format(name, counts[name])) 
      counts[name] += 1 
    return output 

अद्यतन: मैं तय ओपी की तलाश में क्या ठीक से लौटने के लिए मेरे जवाब में कोड। सबसे अच्छा तरीका नहीं है, लेकिन इसे किसी अन्य लाइब्रेरी के उपयोग की आवश्यकता नहीं है और 1 dict समझ और 1 लूप का उपयोग करता है।

+0

'गणना [नाम] 'को' str()' – TemporalWolf

+0

में लपेटने की आवश्यकता है, मुझे विश्वास है कि अब तय किया जाना चाहिए कि मैंने 'प्रारूप' पर स्विच किया है। –

+0

यह उन वस्तुओं पर गिनती करता है जो केवल एक बार दिखाई देते हैं। –

0

आप प्रारंभिक आदेश के बारे में परवाह नहीं है, तो आप इस का इस तरह से सोच सकता है:

  • गणना समय की संख्या प्रत्येक नाम प्रकट होता है
  • एक सूची जहां, अगर नाम ही प्रकट होता है उत्पन्न एक बार, हम कुछ भी नहीं जोड़ते हैं, लेकिन यदि यह एक से अधिक बार प्रकट होता है, तो यह _1, _2 ... दूसरे और बाद के उपस्थितियों में जोड़ता है।

इसका मतलब यह है, तो आप एक collections.Counter का उपयोग काम करवाने के लिए कर सकता है: जो आउटपुट

import collections 

names = ['Alice', 'Bob', 'Carl', 'Dave', 'Bob', 'Earl', 'Carl', 'Frank', 'Carl'] 

counter = collections.Counter(names) 
print("Counter: %s" % counter) 

result = [] 
for name, counts in counter.iteritems(): 
    result.append(name) 
    for i in range(1, counts): 
     result.append("%s_%d" % (name, i)) 
print(result) 

:

Counter: Counter({'Carl': 3, 'Bob': 2, 'Earl': 1, 'Frank': 1, 'Alice': 1, 'Dave': 1}) 
['Earl', 'Frank', 'Alice', 'Dave', 'Carl', 'Carl_1', 'Carl_2', 'Bob', 'Bob_1'] 

आप सभी _1, _2 प्रत्यय जोड़ना चाहते थे, तो जिन नामों में सूची में एक से अधिक घटनाएं हैं, लेकिन उन नामों को छोड़ दें जो केवल एक बार छेड़छाड़ किए जाते हैं, आप कर सकते हैं:

import collections 

names = ['Alice', 'Bob', 'Carl', 'Dave', 'Bob', 'Earl', 'Carl', 'Frank', 'Carl'] 

counter = collections.Counter(names) 
print("Counter: %s" % counter) 

result = [] 
for name, counts in counter.iteritems(): 
    if counts == 1: 
     result.append(name) 
    else: 
     for i in range(counts): 
      result.append("%s_%d" % (name, i + 1)) 
print(result) 

आउटपुट कौन सा:

counts = {} 
def append(name): 
    try: 
     counts[name] += 1 
     return True 
    except: 
     counts[name] = 1 
     return False 

def get_duplicates(): 
    return ['_'.join([name, str(counts[name])]) if append(name) else name for name in names] 

लाभ के लिए:

Counter: Counter({'Carl': 3, 'Bob': 2, 'Earl': 1, 'Frank': 1, 'Alice': 1, 'Dave': 1}) 
['Earl', 'Frank', 'Alice', 'Dave', 'Carl_1', 'Carl_2', 'Carl_3', 'Bob_1', 'Bob_2'] 
0

तो ['Alice', 'Bob', 'Carl', 'Dave', 'Bob_2', 'Earl', 'Carl_2', 'Frank', 'Carl_3'] है स्वीकार्य निर्गम (पहले नहीं होने एक _1 पर जोड़ा व्यक्ति) तो मैं निम्नलिखित सुझाव है यह दृष्टिकोण है कि मैं केवल एक ही समय में names से गुजरता हूं, यही कारण है कि मैं समय से पहले नहीं जान सकता कि क्या अधिक दिखाई देगा।


कल्पना को पूरा करने के लिए, मैं आगे संशोधित कर सकते हैं संलग्न:

def append(name): 
    if names.count(name) != 1: 
     try: 
      counts[name] += 1 
     except: 
      counts[name] = 1 
     return True 
    else: 
     return False 

जो अपेक्षित परिणाम दे देंगे:

['Alice', 'Bob_1', 'Carl_1', 'Dave', 'Bob_2', 'Earl', 'Carl_2', 'Frank', 'Carl_3'] 
0

एक अन्य समाधान है जो उपयोग करता enumerate:

>>> names = ['Alice','Bob','Carl','Dave','Bob','Earl','Carl','Frank','Carl'] 
>>> processed = [] 
>>> for n in names: 
...  if n not in processed: 
...   indices = [i for i,name in enumerate(names) if name == n] 
...   if len(indices) > 1: 
...    suffix = 1 
...    for i in indices: 
...     names[i] = "{}_{}".format(names[i], suffix) 
...     suffix += 1 
...  if n.split('_')[0] not in processed: 
...   processed.append(n) 
... 
>>> 
>>> names 
['Alice', 'Bob_1', 'Carl_1', 'Dave', 'Bob_2', 'Earl', 'Carl_2', 'Frank', 'Carl_3'] 
संबंधित मुद्दे