ฉันจะค้นหารายการที่ซ้ำกันในรายการและสร้างรายการอื่นได้อย่างไร


437

ฉันจะหารายการที่ซ้ำกันในรายการ Python และสร้างรายการที่ซ้ำกันได้อย่างไร รายการมีจำนวนเต็มเท่านั้น



1
คุณต้องการที่ซ้ำกันครั้งเดียวหรือทุกครั้งที่มันเห็นอีกครั้ง?
moooeeeep

ฉันคิดว่านี่เป็นคำตอบที่มีประสิทธิภาพมากขึ้นที่นี่ stackoverflow.com/a/642919/1748045 การแยกเป็นวิธีการตั้งค่าที่มีอยู่แล้วภายในและควรทำสิ่งที่ต้องการอย่างแน่นอน
Tom Smith

คำตอบ:


545

set(a)ในการลบซ้ำกันใช้ หากต้องการพิมพ์รายการที่ซ้ำกันมีลักษณะดังนี้:

a = [1,2,3,2,1,5,6,5,5,5]

import collections
print([item for item, count in collections.Counter(a).items() if count > 1])

## [1, 2, 5]

โปรดทราบว่าCounterไม่มีประสิทธิภาพโดยเฉพาะอย่างยิ่ง (การกำหนดเวลา ) และอาจ overkill ที่นี่ setจะทำงานได้ดีขึ้น รหัสนี้คำนวณรายการองค์ประกอบที่ไม่ซ้ำกันในการสั่งซื้อแหล่งที่มา:

seen = set()
uniq = []
for x in a:
    if x not in seen:
        uniq.append(x)
        seen.add(x)

หรือรัดกุมมากขึ้น:

seen = set()
uniq = [x for x in a if x not in seen and not seen.add(x)]    

ฉันไม่แนะนำสไตล์หลังเนื่องจากไม่ชัดเจนว่าnot seen.add(x)กำลังทำอะไรอยู่ ( add()เมธอดset ส่งคืนเสมอNoneดังนั้นจึงจำเป็นต้องใช้not)

ในการคำนวณรายการองค์ประกอบที่ทำซ้ำโดยไม่มีไลบรารี:

seen = {}
dupes = []

for x in a:
    if x not in seen:
        seen[x] = 1
    else:
        if seen[x] == 1:
            dupes.append(x)
        seen[x] += 1

หากองค์ประกอบรายการไม่แฮชคุณไม่สามารถใช้ชุด / dicts และต้องหันไปใช้วิธีแก้ปัญหากำลังสอง (เปรียบเทียบแต่ละรายการด้วยกัน) ตัวอย่างเช่น:

a = [[1], [2], [3], [1], [5], [3]]

no_dupes = [x for n, x in enumerate(a) if x not in a[:n]]
print no_dupes # [[1], [2], [3], [5]]

dupes = [x for n, x in enumerate(a) if x in a[:n]]
print dupes # [[1], [3]]

2
@ Eric: ผมคิดว่ามันเป็นO(n)เพราะเพียง iterates O(1)รายการครั้งเดียวและชุดการค้นหาเป็น
georg

3
@Hugo เพื่อดูรายการซ้ำเราแค่ต้องสร้างรายการใหม่ที่เรียกว่า dup และเพิ่มคำสั่งอื่น ตัวอย่างเช่น:dup = [] else: dup.append(x)
Chris Nielsen

4
@ oxeimon: คุณอาจได้รับสิ่งนี้ แต่คุณพิมพ์ด้วยวงเล็บในหลาม 3print()
Moberg

4
แปลงคำตอบของคุณสำหรับ set () เพื่อทำซ้ำเท่านั้น seen = set()จากนั้นdupe = set(x for x in a if x in seen or seen.add(x))
Ta946

2
สำหรับ Python 3.x: พิมพ์ ([รายการสำหรับรายการให้นับเป็นคอลเล็กชันตัวนับ (a) .items () ถ้านับ> 1])
kibitzforu

327
>>> l = [1,2,3,4,4,5,5,6,1]
>>> set([x for x in l if l.count(x) > 1])
set([1, 4, 5])

2
มีเหตุผลใดที่คุณใช้ list comprehension แทนที่จะเป็น generator comprehension?

64
แท้จริงแล้วโซลูชันที่เรียบง่าย แต่มีความซับซ้อนกำลังสองเนื่องจากแต่ละการนับ () แยกวิเคราะห์รายการทั้งหมดอีกครั้งดังนั้นอย่าใช้สำหรับรายการขนาดใหญ่
danuker

4
@JohnJ การจัดเรียงฟองก็ง่ายและใช้งานได้ ไม่ได้หมายความว่าเราควรใช้มัน!
John La Rooy

@JohnLaRooy จริง ๆ แล้วหมายความว่าเราไม่ควรใช้เพราะมีวิธีที่มีประสิทธิภาพมากขึ้น (และง่ายกว่า) ในการเรียงลำดับ
lostsoul29

1
@watsonic: "สวิตช์แบบง่าย" ของคุณล้มเหลวในการลดความซับซ้อนของเวลาจากกำลังสองเป็นกำลังสองในกรณีทั่วไป การแทนที่lด้วยการset(l)ลดความซับซ้อนของเวลากรณีที่เลวร้ายที่สุดเท่านั้นและด้วยเหตุนี้จึงไม่ทำอะไรเลยเพื่อจัดการกับปัญหาที่มีขนาดใหญ่ขึ้นด้วยคำตอบนี้ มันอาจจะไม่ง่ายเลยหลังจากทั้งหมด ในระยะสั้นอย่าทำเช่นนี้
เซซิลแกงกะหรี่

82

คุณไม่ต้องการการนับไม่ว่าจะเห็นรายการนั้นมาก่อนหรือไม่ ปรับคำตอบสำหรับปัญหานี้แล้ว:

def list_duplicates(seq):
  seen = set()
  seen_add = seen.add
  # adds all elements it doesn't know yet to seen and all other to seen_twice
  seen_twice = set( x for x in seq if x in seen or seen_add(x) )
  # turn the set into a list (as requested)
  return list( seen_twice )

a = [1,2,3,2,1,5,6,5,5,5]
list_duplicates(a) # yields [1, 2, 5]

ในกรณีที่ความเร็วเป็นเรื่องต่อไปนี้เป็นเวลา

# file: test.py
import collections

def thg435(l):
    return [x for x, y in collections.Counter(l).items() if y > 1]

def moooeeeep(l):
    seen = set()
    seen_add = seen.add
    # adds all elements it doesn't know yet to seen and all other to seen_twice
    seen_twice = set( x for x in l if x in seen or seen_add(x) )
    # turn the set into a list (as requested)
    return list( seen_twice )

def RiteshKumar(l):
    return list(set([x for x in l if l.count(x) > 1]))

def JohnLaRooy(L):
    seen = set()
    seen2 = set()
    seen_add = seen.add
    seen2_add = seen2.add
    for item in L:
        if item in seen:
            seen2_add(item)
        else:
            seen_add(item)
    return list(seen2)

l = [1,2,3,2,1,5,6,5,5,5]*100

นี่คือผลลัพธ์: (ทำได้ดีมาก @JohnLaRooy!)

$ python -mtimeit -s 'import test' 'test.JohnLaRooy(test.l)'
10000 loops, best of 3: 74.6 usec per loop
$ python -mtimeit -s 'import test' 'test.moooeeeep(test.l)'
10000 loops, best of 3: 91.3 usec per loop
$ python -mtimeit -s 'import test' 'test.thg435(test.l)'
1000 loops, best of 3: 266 usec per loop
$ python -mtimeit -s 'import test' 'test.RiteshKumar(test.l)'
100 loops, best of 3: 8.35 msec per loop

ที่น่าสนใจนอกจากการกำหนดเวลาเองการจัดอันดับจะเปลี่ยนไปเล็กน้อยเมื่อใช้ pypy ที่น่าสนใจที่สุดวิธีการแบบ Counter-based นั้นมีประโยชน์อย่างมากจากการปรับแต่งของ pypy ในขณะที่วิธีการแคชที่ฉันแนะนำดูเหมือนจะแทบไม่มีผลกระทบเลย

$ pypy -mtimeit -s 'import test' 'test.JohnLaRooy(test.l)'
100000 loops, best of 3: 17.8 usec per loop
$ pypy -mtimeit -s 'import test' 'test.thg435(test.l)'
10000 loops, best of 3: 23 usec per loop
$ pypy -mtimeit -s 'import test' 'test.moooeeeep(test.l)'
10000 loops, best of 3: 39.3 usec per loop

เห็นได้ชัดว่าเอฟเฟกต์นี้เกี่ยวข้องกับ "ความซ้ำซ้อน" ของข้อมูลอินพุต ฉันได้ตั้งค่าl = [random.randrange(1000000) for i in xrange(10000)]และรับผลลัพธ์เหล่านี้:

$ pypy -mtimeit -s 'import test' 'test.moooeeeep(test.l)'
1000 loops, best of 3: 495 usec per loop
$ pypy -mtimeit -s 'import test' 'test.JohnLaRooy(test.l)'
1000 loops, best of 3: 499 usec per loop
$ pypy -mtimeit -s 'import test' 'test.thg435(test.l)'
1000 loops, best of 3: 1.68 msec per loop

6
แค่อยากรู้อยากเห็น - วัตถุประสงค์ของ seen_add = seen แล้วเพิ่มที่นี่?
Rob

3
@Rob วิธีนี้คุณเพียงแค่เรียกฟังก์ชั่นที่คุณค้นหามาก่อน มิฉะนั้นคุณจะต้องค้นหา (แบบสอบถามในพจนานุกรม) ฟังก์ชั่นสมาชิกaddทุกครั้งที่จำเป็นต้องมีการแทรก
moooeeeep

ตรวจสอบกับข้อมูลของฉันเองและ Ipython% timeit วิธีการของคุณจะดูเร็วที่สุดในการทดสอบ แต่: "การรันที่ช้าที่สุดใช้เวลานานกว่า 4.34 เท่าเร็วที่สุดซึ่งอาจหมายความว่าผลกลางจะถูกแคช"
Joop

1
@moooeeeep ฉันได้เพิ่มเวอร์ชันอื่นลงในสคริปต์ของคุณเพื่อให้คุณลอง :) ลองดูpypyถ้าคุณมีประโยชน์และกำลังเพิ่มความเร็ว
John La Rooy

@JohnLaRooy ปรับปรุงประสิทธิภาพได้ดีมาก! ที่น่าสนใจเมื่อฉันใช้ pypy เพื่อประเมินผลลัพธ์วิธีเคาน์เตอร์อิงจะปรับปรุงอย่างมีนัยสำคัญ
moooeeeep

42

คุณสามารถใช้iteration_utilities.duplicates:

>>> from iteration_utilities import duplicates

>>> list(duplicates([1,1,2,1,2,3,4,2]))
[1, 1, 2, 2]

หรือหากคุณต้องการให้มีหนึ่งในสำเนาที่ซ้ำกันซึ่งสามารถรวมกับiteration_utilities.unique_everseen:

>>> from iteration_utilities import unique_everseen

>>> list(unique_everseen(duplicates([1,1,2,1,2,3,4,2])))
[1, 2]

นอกจากนี้ยังสามารถจัดการองค์ประกอบที่ไม่สามารถล้างได้ (แต่ต้องเสียค่าใช้จ่ายที่ประสิทธิภาพ):

>>> list(duplicates([[1], [2], [1], [3], [1]]))
[[1], [1]]

>>> list(unique_everseen(duplicates([[1], [2], [1], [3], [1]])))
[[1]]

นั่นเป็นสิ่งที่มีเพียงไม่กี่วิธีที่สามารถจัดการได้

มาตรฐาน

ฉันทำเกณฑ์มาตรฐานอย่างรวดเร็วซึ่งมีแนวทางที่กล่าวถึงที่นี่ (แต่ไม่ใช่ทั้งหมด)

เกณฑ์มาตรฐานแรกรวมช่วงความยาวรายการเพียงเล็กน้อยเท่านั้นเนื่องจากบางแนวทางมีO(n**2)พฤติกรรม

ในกราฟแกน y แสดงเวลาดังนั้นค่าที่ต่ำกว่าจึงหมายถึงดีกว่า นอกจากนี้ยังมีการพล็อตล็อกบันทึกเพื่อให้สามารถมองเห็นค่าได้หลากหลาย:

ป้อนคำอธิบายรูปภาพที่นี่

การลบO(n**2)วิธีการที่ฉันได้ทำมาตรฐานอื่น ๆ ถึงครึ่งล้านองค์ประกอบในรายการ:

ป้อนคำอธิบายรูปภาพที่นี่

คุณจะเห็นว่าiteration_utilities.duplicatesวิธีการนั้นเร็วกว่าวิธีอื่น ๆ และแม้แต่การผูกมัดunique_everseen(duplicates(...))นั้นเร็วกว่าหรือเร็วกว่าวิธีอื่น ๆ

อีกสิ่งที่น่าสนใจเพิ่มเติมที่ควรทราบที่นี่คือวิธีการของ pandas นั้นช้ามากสำหรับรายการขนาดเล็ก

อย่างไรก็ตามเนื่องจากมาตรฐานเหล่านี้แสดงวิธีการส่วนใหญ่ที่ดำเนินการอย่างเท่าเทียมกันดังนั้นจึงไม่สำคัญว่าจะใช้วิธีใด (ยกเว้น 3 ที่O(n**2)ใช้งานจริง)

from iteration_utilities import duplicates, unique_everseen
from collections import Counter
import pandas as pd
import itertools

def georg_counter(it):
    return [item for item, count in Counter(it).items() if count > 1]

def georg_set(it):
    seen = set()
    uniq = []
    for x in it:
        if x not in seen:
            uniq.append(x)
            seen.add(x)

def georg_set2(it):
    seen = set()
    return [x for x in it if x not in seen and not seen.add(x)]   

def georg_set3(it):
    seen = {}
    dupes = []

    for x in it:
        if x not in seen:
            seen[x] = 1
        else:
            if seen[x] == 1:
                dupes.append(x)
            seen[x] += 1

def RiteshKumar_count(l):
    return set([x for x in l if l.count(x) > 1])

def moooeeeep(seq):
    seen = set()
    seen_add = seen.add
    # adds all elements it doesn't know yet to seen and all other to seen_twice
    seen_twice = set( x for x in seq if x in seen or seen_add(x) )
    # turn the set into a list (as requested)
    return list( seen_twice )

def F1Rumors_implementation(c):
    a, b = itertools.tee(sorted(c))
    next(b, None)
    r = None
    for k, g in zip(a, b):
        if k != g: continue
        if k != r:
            yield k
            r = k

def F1Rumors(c):
    return list(F1Rumors_implementation(c))

def Edward(a):
    d = {}
    for elem in a:
        if elem in d:
            d[elem] += 1
        else:
            d[elem] = 1
    return [x for x, y in d.items() if y > 1]

def wordsmith(a):
    return pd.Series(a)[pd.Series(a).duplicated()].values

def NikhilPrabhu(li):
    li = li.copy()
    for x in set(li):
        li.remove(x)

    return list(set(li))

def firelynx(a):
    vc = pd.Series(a).value_counts()
    return vc[vc > 1].index.tolist()

def HenryDev(myList):
    newList = set()

    for i in myList:
        if myList.count(i) >= 2:
            newList.add(i)

    return list(newList)

def yota(number_lst):
    seen_set = set()
    duplicate_set = set(x for x in number_lst if x in seen_set or seen_set.add(x))
    return seen_set - duplicate_set

def IgorVishnevskiy(l):
    s=set(l)
    d=[]
    for x in l:
        if x in s:
            s.remove(x)
        else:
            d.append(x)
    return d

def it_duplicates(l):
    return list(duplicates(l))

def it_unique_duplicates(l):
    return list(unique_everseen(duplicates(l)))

เกณฑ์มาตรฐาน 1

from simple_benchmark import benchmark
import random

funcs = [
    georg_counter, georg_set, georg_set2, georg_set3, RiteshKumar_count, moooeeeep, 
    F1Rumors, Edward, wordsmith, NikhilPrabhu, firelynx,
    HenryDev, yota, IgorVishnevskiy, it_duplicates, it_unique_duplicates
]

args = {2**i: [random.randint(0, 2**(i-1)) for _ in range(2**i)] for i in range(2, 12)}

b = benchmark(funcs, args, 'list size')

b.plot()

เกณฑ์มาตรฐาน 2

funcs = [
    georg_counter, georg_set, georg_set2, georg_set3, moooeeeep, 
    F1Rumors, Edward, wordsmith, firelynx,
    yota, IgorVishnevskiy, it_duplicates, it_unique_duplicates
]

args = {2**i: [random.randint(0, 2**(i-1)) for _ in range(2**i)] for i in range(2, 20)}

b = benchmark(funcs, args, 'list size')
b.plot()

คำปฏิเสธ

1 นี้มาจากห้องสมุดบุคคลที่สามที่ฉันเขียน: iteration_utilities.


1
ฉันจะติดคอของฉันที่นี่และแนะนำให้เขียนห้องสมุด bespoke เพื่อทำงานใน C มากกว่า Python อาจไม่ใช่วิญญาณของคำตอบที่ถูกมองหา - แต่นั่นเป็นวิธีที่ถูกต้องตามกฎหมาย! ฉันชอบความกว้างของคำตอบและการแสดงผลกราฟิก - ดีมากที่ได้เห็นพวกเขามาบรรจบกันทำให้ฉันสงสัยว่าพวกเขาเคยข้ามเมื่ออินพุตเพิ่มขึ้นอีกหรือไม่! คำถาม: ผลลัพธ์ที่มีรายการที่เรียงลำดับส่วนใหญ่เมื่อเทียบกับรายการที่สุ่มสมบูรณ์คืออะไร
F1Rumors

30

ฉันเจอคำถามนี้ในขณะที่มองหาบางสิ่งที่เกี่ยวข้อง - และสงสัยว่าทำไมไม่มีใครเสนอโซลูชันที่ใช้ตัวสร้าง? การแก้ปัญหานี้จะเป็น:

>>> print list(getDupes_9([1,2,3,2,1,5,6,5,5,5]))
[1, 2, 5]

ฉันเกี่ยวข้องกับความสามารถในการปรับขนาดได้ดังนั้นทดสอบหลายวิธีรวมถึงรายการที่ไร้เดียงสาที่ทำงานได้ดีในรายการขนาดเล็ก แต่เพิ่มขนาดอย่างน่ากลัวเมื่อรายการมีขนาดใหญ่ขึ้น (หมายเหตุ - ควรใช้ timeit ดีกว่า แต่นี่เป็นตัวอย่าง)

ฉันรวม @moooeeeep เพื่อเปรียบเทียบ (มันรวดเร็วน่าประทับใจ: เร็วที่สุดถ้ารายการอินพุตเป็นแบบสุ่มทั้งหมด) และวิธีการ itertools ที่เร็วยิ่งขึ้นอีกครั้งสำหรับรายการที่เรียงลำดับส่วนใหญ่ ... ตอนนี้มีวิธีการ pandas จาก @f allnx - ช้า แต่ไม่ อย่างน่ากลัวและเรียบง่าย หมายเหตุ - วิธีการเรียงลำดับ / ทีออฟ / ซิปนั้นเร็วที่สุดในเครื่องของฉันสำหรับรายการที่สั่งซื้อจำนวนมากส่วนใหญ่ moooeeeep นั้นเร็วที่สุดสำหรับรายการที่สับแล้ว แต่ระยะทางของคุณอาจเปลี่ยนแปลง

ข้อดี

  • ง่ายมากในการทดสอบการซ้ำซ้อน 'ใด ๆ ' โดยใช้รหัสเดียวกัน

สมมติฐาน

  • ควรรายงานซ้ำกันเพียงครั้งเดียว
  • ไม่ต้องรักษาลำดับที่ซ้ำกัน
  • รายการซ้ำอาจอยู่ที่ใดก็ได้ในรายการ

วิธีแก้ปัญหาที่เร็วที่สุดรายการ 1m:

def getDupes(c):
        '''sort/tee/izip'''
        a, b = itertools.tee(sorted(c))
        next(b, None)
        r = None
        for k, g in itertools.izip(a, b):
            if k != g: continue
            if k != r:
                yield k
                r = k

แนวทางการทดสอบ

import itertools
import time
import random

def getDupes_1(c):
    '''naive'''
    for i in xrange(0, len(c)):
        if c[i] in c[:i]:
            yield c[i]

def getDupes_2(c):
    '''set len change'''
    s = set()
    for i in c:
        l = len(s)
        s.add(i)
        if len(s) == l:
            yield i

def getDupes_3(c):
    '''in dict'''
    d = {}
    for i in c:
        if i in d:
            if d[i]:
                yield i
                d[i] = False
        else:
            d[i] = True

def getDupes_4(c):
    '''in set'''
    s,r = set(),set()
    for i in c:
        if i not in s:
            s.add(i)
        elif i not in r:
            r.add(i)
            yield i

def getDupes_5(c):
    '''sort/adjacent'''
    c = sorted(c)
    r = None
    for i in xrange(1, len(c)):
        if c[i] == c[i - 1]:
            if c[i] != r:
                yield c[i]
                r = c[i]

def getDupes_6(c):
    '''sort/groupby'''
    def multiple(x):
        try:
            x.next()
            x.next()
            return True
        except:
            return False
    for k, g in itertools.ifilter(lambda x: multiple(x[1]), itertools.groupby(sorted(c))):
        yield k

def getDupes_7(c):
    '''sort/zip'''
    c = sorted(c)
    r = None
    for k, g in zip(c[:-1],c[1:]):
        if k == g:
            if k != r:
                yield k
                r = k

def getDupes_8(c):
    '''sort/izip'''
    c = sorted(c)
    r = None
    for k, g in itertools.izip(c[:-1],c[1:]):
        if k == g:
            if k != r:
                yield k
                r = k

def getDupes_9(c):
    '''sort/tee/izip'''
    a, b = itertools.tee(sorted(c))
    next(b, None)
    r = None
    for k, g in itertools.izip(a, b):
        if k != g: continue
        if k != r:
            yield k
            r = k

def getDupes_a(l):
    '''moooeeeep'''
    seen = set()
    seen_add = seen.add
    # adds all elements it doesn't know yet to seen and all other to seen_twice
    for x in l:
        if x in seen or seen_add(x):
            yield x

def getDupes_b(x):
    '''iter*/sorted'''
    x = sorted(x)
    def _matches():
        for k,g in itertools.izip(x[:-1],x[1:]):
            if k == g:
                yield k
    for k, n in itertools.groupby(_matches()):
        yield k

def getDupes_c(a):
    '''pandas'''
    import pandas as pd
    vc = pd.Series(a).value_counts()
    i = vc[vc > 1].index
    for _ in i:
        yield _

def hasDupes(fn,c):
    try:
        if fn(c).next(): return True    # Found a dupe
    except StopIteration:
        pass
    return False

def getDupes(fn,c):
    return list(fn(c))

STABLE = True
if STABLE:
    print 'Finding FIRST then ALL duplicates, single dupe of "nth" placed element in 1m element array'
else:
    print 'Finding FIRST then ALL duplicates, single dupe of "n" included in randomised 1m element array'
for location in (50,250000,500000,750000,999999):
    for test in (getDupes_2, getDupes_3, getDupes_4, getDupes_5, getDupes_6,
                 getDupes_8, getDupes_9, getDupes_a, getDupes_b, getDupes_c):
        print 'Test %-15s:%10d - '%(test.__doc__ or test.__name__,location),
        deltas = []
        for FIRST in (True,False):
            for i in xrange(0, 5):
                c = range(0,1000000)
                if STABLE:
                    c[0] = location
                else:
                    c.append(location)
                    random.shuffle(c)
                start = time.time()
                if FIRST:
                    print '.' if location == test(c).next() else '!',
                else:
                    print '.' if [location] == list(test(c)) else '!',
                deltas.append(time.time()-start)
            print ' -- %0.3f  '%(sum(deltas)/len(deltas)),
        print
    print

ผลลัพธ์สำหรับการทดสอบ 'ทุกคน' มีความสอดคล้องกันการค้นหา "ที่ซ้ำกัน" ครั้งแรกและจากนั้น "ทั้งหมด" ที่ซ้ำกันในอาร์เรย์นี้:

Finding FIRST then ALL duplicates, single dupe of "nth" placed element in 1m element array
Test set len change :    500000 -  . . . . .  -- 0.264   . . . . .  -- 0.402  
Test in dict        :    500000 -  . . . . .  -- 0.163   . . . . .  -- 0.250  
Test in set         :    500000 -  . . . . .  -- 0.163   . . . . .  -- 0.249  
Test sort/adjacent  :    500000 -  . . . . .  -- 0.159   . . . . .  -- 0.229  
Test sort/groupby   :    500000 -  . . . . .  -- 0.860   . . . . .  -- 1.286  
Test sort/izip      :    500000 -  . . . . .  -- 0.165   . . . . .  -- 0.229  
Test sort/tee/izip  :    500000 -  . . . . .  -- 0.145   . . . . .  -- 0.206  *
Test moooeeeep      :    500000 -  . . . . .  -- 0.149   . . . . .  -- 0.232  
Test iter*/sorted   :    500000 -  . . . . .  -- 0.160   . . . . .  -- 0.221  
Test pandas         :    500000 -  . . . . .  -- 0.493   . . . . .  -- 0.499  

เมื่อรายการถูกสับเป็นอันดับแรกราคาของการจัดเรียงจะปรากฏขึ้นอย่างมีประสิทธิภาพลดลงอย่างเห็นได้ชัดและวิธีการ @moooeeeep มีอำนาจเหนือกว่าด้วยวิธีการตั้งค่า & dict จะคล้ายกัน แต่มีประสิทธิภาพน้อยกว่า:

Finding FIRST then ALL duplicates, single dupe of "n" included in randomised 1m element array
Test set len change :    500000 -  . . . . .  -- 0.321   . . . . .  -- 0.473  
Test in dict        :    500000 -  . . . . .  -- 0.285   . . . . .  -- 0.360  
Test in set         :    500000 -  . . . . .  -- 0.309   . . . . .  -- 0.365  
Test sort/adjacent  :    500000 -  . . . . .  -- 0.756   . . . . .  -- 0.823  
Test sort/groupby   :    500000 -  . . . . .  -- 1.459   . . . . .  -- 1.896  
Test sort/izip      :    500000 -  . . . . .  -- 0.786   . . . . .  -- 0.845  
Test sort/tee/izip  :    500000 -  . . . . .  -- 0.743   . . . . .  -- 0.804  
Test moooeeeep      :    500000 -  . . . . .  -- 0.234   . . . . .  -- 0.311  *
Test iter*/sorted   :    500000 -  . . . . .  -- 0.776   . . . . .  -- 0.840  
Test pandas         :    500000 -  . . . . .  -- 0.539   . . . . .  -- 0.540  

@moooeeeep - สนใจที่จะเห็นมุมมองของคุณเกี่ยวกับวิธี ifilter / izip / tee
F1Rumors

1
คำตอบนี้เป็นสิ่งที่ดีอย่างเหลือเชื่อฉันไม่เข้าใจว่ามันไม่มีคะแนนเพิ่มเติมสำหรับคำอธิบายและการทดสอบที่มีประโยชน์มากสำหรับผู้ที่ต้องการมัน
dlewin

1
การเรียงลำดับของ python คือ O (n) เมื่อมีเพียงรายการเดียวที่ไม่ได้รับคำสั่ง คุณควรrandom.shuffle(c)คำนึงถึงสิ่งนั้น นอกจากนี้ฉันไม่สามารถจำลองผลลัพธ์ของคุณเมื่อรันสคริปต์ที่ไม่เปลี่ยนแปลงเช่นกัน (เรียงลำดับแตกต่างกันโดยสิ้นเชิง) ดังนั้นบางทีมันก็ขึ้นอยู่กับ CPU ด้วยเช่นกัน
John La Rooy

ขอบคุณ @ จอห์น-La-Rooy สังเกตที่ชาญฉลาดใน CPU เครื่อง / ท้องถิ่นเป็นผลกระทบ - ดังนั้นฉันควรแก้ไขรายการYYMV ใช้การเรียงลำดับO (n)โดยเจตนา: องค์ประกอบที่ซ้ำกันจะถูกแทรกในสถานที่ต่างกันโดยเฉพาะเพื่อดูผลกระทบของวิธีการหากมีการทำซ้ำเพียงอย่างเดียวในสถานที่ที่ดี (เริ่มต้นรายการ) หรือไม่ดี (สิ้นสุดรายการ) วิธีการ ฉันถือว่าเป็นรายการแบบสุ่ม - เช่นสุ่มสลับ - แต่ตัดสินใจว่าจะสมเหตุสมผลถ้าฉันวิ่งอีกมาก! ฉันจะต้องกลับมาและเปรียบเทียบการวิ่ง / สับเปลี่ยนหลายครั้งและดูว่าผลกระทบคืออะไร
F1Rumors

แก้ไขให้รวมวิธีการ @fAllnx pandas & เพื่อเรียกใช้บนรายการที่สับแบบเต็มเช่นเดียวกับรายการที่เรียงลำดับ นี่เป็นเพราะ timsort ดั้งเดิมที่ใช้โดย Python นั้นชั่วร้ายอย่างรวดเร็วในข้อมูลที่เรียงลำดับส่วนใหญ่ (กรณีที่ดีที่สุด) และรายการที่สับเป็นกรณีสถานการณ์ที่เลวร้ายที่สุดซึ่งจะทำให้ผลลัพธ์สั่นสะเทือน
F1Rumors


10

คอลเล็กชันตัวนับใหม่ใน python 2.7:


Python 2.5.4 (r254:67916, May 31 2010, 15:03:39) 
[GCC 4.1.2 20080704 (Red Hat 4.1.2-46)] on linux2
a = [1,2,3,2,1,5,6,5,5,5]
import collections
print [x for x, y in collections.Counter(a).items() if y > 1]
Type "help", "copyright", "credits" or "license" for more information.
  File "", line 1, in 
AttributeError: 'module' object has no attribute 'Counter'
>>> 

ในเวอร์ชันก่อนหน้านี้คุณสามารถใช้ dict แบบเดิมแทน:

a = [1,2,3,2,1,5,6,5,5,5]
d = {}
for elem in a:
    if elem in d:
        d[elem] += 1
    else:
        d[elem] = 1

print [x for x, y in d.items() if y > 1]

9

นี่เป็นวิธีที่เรียบร้อยและรัดกุม -

for x in set(li):
    li.remove(x)

li = list(set(li))

แม้ว่ารายการดั้งเดิมจะหายไป สิ่งนี้สามารถแก้ไขได้โดยการคัดลอกเนื้อหาไปยังรายการอื่น - temp = li [:]
Nikhil Prabhu

3
นั่นเป็นการออกกำลังกายที่น่ารังเกียจในรายการขนาดใหญ่การลบองค์ประกอบออกจากรายการค่อนข้างแพง!
F1Rumors

7

โดยไม่ต้องแปลงเป็นลิสต์และอาจเป็นวิธีที่ง่ายที่สุดที่จะเป็นดังนี้ สิ่งนี้อาจเป็นประโยชน์ในระหว่างการสัมภาษณ์เมื่อพวกเขาขอไม่ให้ใช้ชุด

a=[1,2,3,3,3]
dup=[]
for each in a:
  if each not in dup:
    dup.append(each)
print(dup)

======= เพื่อรับ 2 รายการแยกกันซึ่งมีค่าไม่ซ้ำกันและค่าซ้ำกัน

a=[1,2,3,3,3]
uniques=[]
dups=[]

for each in a:
  if each not in uniques:
    uniques.append(each)
  else:
    dups.append(each)
print("Unique values are below:")
print(uniques)
print("Duplicate values are below:")
print(dups)

1
สิ่งนี้จะไม่ส่งผลให้เกิดรายการที่ซ้ำกันของ (หรือรายการดั้งเดิม) แต่ผลลัพธ์นี้จะแสดงรายการองค์ประกอบที่เป็นเอกลักษณ์ทั้งหมดของ (หรือรายการดั้งเดิม) บางคนจะทำอะไรหลังจากที่พวกเขาสร้างรายการ "dup" เสร็จแล้ว
gameCoder95

6

ฉันจะทำแบบนี้กับหมีแพนด้าเพราะฉันใช้แพนด้ามาก

import pandas as pd
a = [1,2,3,3,3,4,5,6,6,7]
vc = pd.Series(a).value_counts()
vc[vc > 1].index.tolist()

จะช่วยให้

[3,6]

อาจไม่มีประสิทธิภาพมาก แต่แน่ใจว่ารหัสน้อยกว่าคำตอบอื่น ๆ จำนวนมากดังนั้นฉันคิดว่าฉันจะมีส่วนร่วม


3
โปรดทราบว่านุ่นมีฟังก์ชั่นซ้ำซ้อนในตัว pda = pd.Series(a) print list(pda[pda.duplicated()])
Len Blokken

6

ตัวอย่างที่สามของคำตอบที่ยอมรับนั้นให้คำตอบที่ผิดพลาดและไม่พยายามให้คำตอบที่ซ้ำกัน นี่คือรุ่นที่ถูกต้อง:

number_lst = [1, 1, 2, 3, 5, ...]

seen_set = set()
duplicate_set = set(x for x in number_lst if x in seen_set or seen_set.add(x))
unique_set = seen_set - duplicate_set

6

วิธีการเกี่ยวกับวนรอบแต่ละองค์ประกอบในรายการโดยการตรวจสอบจำนวนของเหตุการณ์ที่เกิดขึ้นแล้วเพิ่มลงในชุดซึ่งจะพิมพ์รายการที่ซ้ำกัน หวังว่านี่จะช่วยให้ใครบางคนที่นั่น

myList  = [2 ,4 , 6, 8, 4, 6, 12];
newList = set()

for i in myList:
    if myList.count(i) >= 2:
        newList.add(i)

print(list(newList))
## [4 , 6]

5

เราสามารถใช้itertools.groupbyเพื่อค้นหารายการทั้งหมดที่มี dups:

from itertools import groupby

myList  = [2, 4, 6, 8, 4, 6, 12]
# when the list is sorted, groupby groups by consecutive elements which are similar
for x, y in groupby(sorted(myList)):
    #  list(y) returns all the occurences of item x
    if len(list(y)) > 1:
        print x  

ผลลัพธ์จะเป็น:

4
6

1
หรือมากกว่ารัดกุม:dupes = [x for x, y in groupby(sorted(myList)) if len(list(y)) > 1]
frnhr

5

ฉันเดาวิธีที่มีประสิทธิภาพที่สุดในการค้นหารายการที่ซ้ำกันในรายการคือ:

from collections import Counter

def duplicates(values):
    dups = Counter(values) - Counter(set(values))
    return list(dups.keys())

print(duplicates([1,2,3,6,5,2]))

มันใช้Counterองค์ประกอบทั้งหมดและองค์ประกอบที่ไม่ซ้ำกันทั้งหมด การลบอันที่หนึ่งด้วยอันที่สองจะเป็นการลบข้อมูลที่ซ้ำกันเท่านั้น


4

สายไปหน่อย แต่อาจมีประโยชน์สำหรับบางคน สำหรับรายการที่ใหญ่โตฉันพบว่ามันใช้งานได้สำหรับฉัน

l=[1,2,3,5,4,1,3,1]
s=set(l)
d=[]
for x in l:
    if x in s:
        s.remove(x)
    else:
        d.append(x)
d
[1,3,1]

แสดงรายการที่ซ้ำกันทั้งหมดและรักษาลำดับ


3

วิธีที่ง่ายและรวดเร็วในการค้นหา dupes ด้วยการวนซ้ำหนึ่งครั้งใน Python คือ:

testList = ['red', 'blue', 'red', 'green', 'blue', 'blue']

testListDict = {}

for item in testList:
  try:
    testListDict[item] += 1
  except:
    testListDict[item] = 1

print testListDict

ผลลัพธ์จะเป็นดังนี้:

>>> print testListDict
{'blue': 3, 'green': 1, 'red': 2}

สิ่งนี้และอีกมากมายในบล็อกของฉันhttp://www.howtoprogramwithpython.com


3

ฉันเข้ามาช้ามากในการสนทนานี้ แม้ว่าฉันอยากจะจัดการกับปัญหานี้กับหนึ่ง liners เพราะนั่นคือเสน่ห์ของ Python หากเราต้องการได้รับสิ่งที่ซ้ำกันในรายการแยกต่างหาก (หรือคอลเลกชันใด ๆ ) ฉันขอแนะนำให้ทำดังนี้ด้านล่างเรามีรายการที่ซ้ำซึ่งเราสามารถเรียกว่า 'เป้าหมาย'

    target=[1,2,3,4,4,4,3,5,6,8,4,3]

ตอนนี้ถ้าเราต้องการได้ข้อมูลที่ซ้ำกันเราสามารถใช้สายการบินเดียวดังต่อไปนี้:

    duplicates=dict(set((x,target.count(x)) for x in filter(lambda rec : target.count(rec)>1,target)))

รหัสนี้จะใส่ระเบียนที่ซ้ำกันเป็นคีย์และนับเป็นค่าในพจนานุกรม 'ซ้ำ' พจนานุกรม 'ซ้ำ' จะมีลักษณะดังนี้:

    {3: 3, 4: 4} #it saying 3 is repeated 3 times and 4 is 4 times

หากคุณต้องการให้ระเบียนทั้งหมดที่มีรายการซ้ำอยู่คนเดียวในรายการรหัสที่สั้นกว่าของมันก็คือ:

    duplicates=filter(lambda rec : target.count(rec)>1,target)

ผลลัพธ์จะเป็น:

    [3, 4, 4, 4, 3, 4, 3]

มันทำงานได้อย่างสมบูรณ์ใน python 2.7.x + เวอร์ชั่น


3

Python 3.8 หนึ่งซับถ้าคุณไม่สนใจที่จะเขียนอัลกอริทึมของคุณเองหรือใช้ห้องสมุด:

l = [1,2,3,2,1,5,6,5,5,5]

res = [(x, count) for x, g in groupby(sorted(l)) if (count := len(list(g))) > 1]

print(res)

พิมพ์รายการและนับ:

[(1, 2), (2, 2), (5, 4)]

groupbyรับฟังก์ชั่นการจัดกลุ่มเพื่อให้คุณสามารถกำหนดการจัดกลุ่มของคุณในวิธีที่ต่างกันและส่งคืนTupleเขตข้อมูลเพิ่มเติมตามต้องการ

groupby ขี้เกียจดังนั้นไม่ควรช้าเกินไป


2

การทดสอบอื่น ๆ แน่นอนว่าต้องทำ ...

set([x for x in l if l.count(x) > 1])

... แพงเกินไป มันเร็วกว่าประมาณ 500 เท่า (อาร์เรย์ที่ยาวกว่าจะให้ผลลัพธ์ที่ดีกว่า) เพื่อใช้วิธีสุดท้ายต่อไป:

def dups_count_dict(l):
    d = {}

    for item in l:
        if item not in d:
            d[item] = 0

        d[item] += 1

    result_d = {key: val for key, val in d.iteritems() if val > 1}

    return result_d.keys()

เพียง 2 ลูปไม่มีl.count()การดำเนินการที่มีราคาแพงมาก

นี่คือรหัสเพื่อเปรียบเทียบวิธีการเช่น รหัสด้านล่างนี่คือผลลัพธ์:

dups_count: 13.368s # this is a function which uses l.count()
dups_count_dict: 0.014s # this is a final best function (of the 3 functions)
dups_count_counter: 0.024s # collections.Counter

รหัสการทดสอบ:

import numpy as np
from time import time
from collections import Counter

class TimerCounter(object):
    def __init__(self):
        self._time_sum = 0

    def start(self):
        self.time = time()

    def stop(self):
        self._time_sum += time() - self.time

    def get_time_sum(self):
        return self._time_sum


def dups_count(l):
    return set([x for x in l if l.count(x) > 1])


def dups_count_dict(l):
    d = {}

    for item in l:
        if item not in d:
            d[item] = 0

        d[item] += 1

    result_d = {key: val for key, val in d.iteritems() if val > 1}

    return result_d.keys()


def dups_counter(l):
    counter = Counter(l)    

    result_d = {key: val for key, val in counter.iteritems() if val > 1}

    return result_d.keys()



def gen_array():
    np.random.seed(17)
    return list(np.random.randint(0, 5000, 10000))


def assert_equal_results(*results):
    primary_result = results[0]
    other_results = results[1:]

    for other_result in other_results:
        assert set(primary_result) == set(other_result) and len(primary_result) == len(other_result)


if __name__ == '__main__':
    dups_count_time = TimerCounter()
    dups_count_dict_time = TimerCounter()
    dups_count_counter = TimerCounter()

    l = gen_array()

    for i in range(3):
        dups_count_time.start()
        result1 = dups_count(l)
        dups_count_time.stop()

        dups_count_dict_time.start()
        result2 = dups_count_dict(l)
        dups_count_dict_time.stop()

        dups_count_counter.start()
        result3 = dups_counter(l)
        dups_count_counter.stop()

        assert_equal_results(result1, result2, result3)

    print 'dups_count: %.3f' % dups_count_time.get_time_sum()
    print 'dups_count_dict: %.3f' % dups_count_dict_time.get_time_sum()
    print 'dups_count_counter: %.3f' % dups_count_counter.get_time_sum()

2

วิธีที่ 1:

list(set([val for idx, val in enumerate(input_list) if val in input_list[idx+1:]]))

คำอธิบาย: [val สำหรับ idx, val ใน enumerate (input_list) ถ้า val ใน input_list [idx + 1:]] เป็นรายการความเข้าใจที่ส่งกลับองค์ประกอบหากองค์ประกอบเดียวกันมีอยู่จากตำแหน่งปัจจุบันในรายการดัชนี .

ตัวอย่าง: input_list = [42,31,42,31,3,31,31,5,6,6,6,6,6,6,6,6,7,42]

เริ่มต้นด้วยองค์ประกอบแรกในรายการ 42 กับดัชนี 0 จะตรวจสอบว่าองค์ประกอบ 42 มีอยู่ใน input_list [1:] (เช่นจากดัชนี 1 จนถึงจุดสิ้นสุดรายการ) เนื่องจาก 42 มีอยู่ใน input_list [1:] มันจะกลับ 42

จากนั้นไปที่องค์ประกอบถัดไปที่ 31 โดยมีดัชนี 1 และตรวจสอบว่าองค์ประกอบ 31 นั้นมีอยู่ใน input_list [2:] (เช่นจากดัชนี 2 จนถึงตอนท้ายของรายการ) เนื่องจาก 31 มีอยู่ใน input_list [2:] มันจะกลับ 31

มันจะผ่านองค์ประกอบทั้งหมดในรายการและจะส่งกลับองค์ประกอบที่ซ้ำกัน / ซ้ำไปยังรายการเท่านั้น

จากนั้นเนื่องจากเรามีรายการที่ซ้ำกันเราจึงต้องเลือกรายการที่ซ้ำกันหนึ่งรายการนั่นคือลบรายการที่ซ้ำกันออกจากรายการที่ซ้ำกันและเราจะเรียกชุดชื่อในตัวของหลาม () และจะลบรายการที่ซ้ำกันออก

จากนั้นเราจะเหลือชุด แต่ไม่ใช่รายการและด้วยเหตุนี้เมื่อต้องการแปลงจากชุดเป็นรายการเราใช้ typecasting, list () และแปลงชุดขององค์ประกอบเป็นรายการ

วิธีที่ 2:

def dupes(ilist):
    temp_list = [] # initially, empty temporary list
    dupe_list = [] # initially, empty duplicate list
    for each in ilist:
        if each in temp_list: # Found a Duplicate element
            if not each in dupe_list: # Avoid duplicate elements in dupe_list
                dupe_list.append(each) # Add duplicate element to dupe_list
        else: 
            temp_list.append(each) # Add a new (non-duplicate) to temp_list

    return dupe_list

คำอธิบาย: ที่ นี่เราสร้างสองรายการที่ว่างเปล่าเพื่อเริ่มต้นด้วย จากนั้นตรวจสอบองค์ประกอบทั้งหมดของรายการเพื่อดูว่ามีอยู่ใน temp_list (ว่างเปล่าในตอนแรก) หรือไม่ หากไม่มีอยู่ใน temp_list เราจะเพิ่มใน temp_list โดยใช้วิธีการต่อท้าย

หากมีอยู่แล้วใน temp_list ก็หมายความว่าองค์ประกอบปัจจุบันของรายการนั้นซ้ำกันและด้วยเหตุนี้เราจำเป็นต้องเพิ่มลงใน dupe_list โดยใช้วิธีการต่อท้าย


2
raw_list = [1,2,3,3,4,5,6,6,7,2,3,4,2,3,4,1,3,4,]

clean_list = list(set(raw_list))
duplicated_items = []

for item in raw_list:
    try:
        clean_list.remove(item)
    except ValueError:
        duplicated_items.append(item)


print(duplicated_items)
# [3, 6, 2, 3, 4, 2, 3, 4, 1, 3, 4]

คุณพื้นลบรายการที่ซ้ำโดยการแปลงชุด ( clean_list) แล้วย้ำraw_listในขณะที่แต่ละลบในรายการที่สะอาดสำหรับการเกิดขึ้นในitem raw_listหากitemไม่พบValueErrorข้อยกเว้นที่ยกขึ้นจะถูกจับและitemเพิ่มลงในduplicated_itemsรายการ

หากต้องการดัชนีของรายการที่ซ้ำกันเพียงenumerateรายการและเล่นกับดัชนี ( for index, item in enumerate(raw_list):) ซึ่งเร็วกว่าและปรับให้เหมาะสมสำหรับรายการขนาดใหญ่ (เช่นองค์ประกอบหลายพันรายการ)


2

ใช้list.count()วิธีการในรายการเพื่อค้นหาองค์ประกอบที่ซ้ำกันของรายการที่กำหนด

arr=[]
dup =[]
for i in range(int(input("Enter range of list: "))):
    arr.append(int(input("Enter Element in a list: ")))
for i in arr:
    if arr.count(i)>1 and i not in dup:
        dup.append(i)
print(dup)

วิธีง่ายๆในการค้นหาองค์ประกอบที่ซ้ำกันในรายการโดยใช้ฟังก์ชั่นการนับ
Ravikiran D

2

หนึ่งซับเพื่อความสนุกสนานและในกรณีที่จำเป็นต้องมีคำสั่งเดียว

(lambda iterable: reduce(lambda (uniq, dup), item: (uniq, dup | {item}) if item in uniq else (uniq | {item}, dup), iterable, (set(), set())))(some_iterable)



1

มีคำตอบมากมายที่นี่ แต่ฉันคิดว่านี่เป็นวิธีที่อ่านได้ง่ายและเข้าใจได้ง่ายมาก:

def get_duplicates(sorted_list):
    duplicates = []
    last = sorted_list[0]
    for x in sorted_list[1:]:
        if x == last:
            duplicates.append(x)
        last = x
    return set(duplicates)

หมายเหตุ:

  • หากคุณต้องการรักษาจำนวนการทำซ้ำให้กำจัด cast ไปที่ 'set' ที่ด้านล่างเพื่อรับรายการทั้งหมด
  • หากคุณต้องการใช้เครื่องกำเนิดไฟฟ้าให้แทนที่รายการซ้ำผนวก (x)ด้วยอัตราผลตอบแทน xและคำสั่งส่งคืนที่ด้านล่าง (คุณสามารถส่งเพื่อตั้งค่าในภายหลัง)

1

ต่อไปนี้เป็นตัวสร้างที่รวดเร็วซึ่งใช้ dict เพื่อจัดเก็บองค์ประกอบแต่ละรายการเป็นคีย์ที่มีค่าบูลีนสำหรับตรวจสอบว่ารายการที่ซ้ำกันได้รับผลไปแล้ว

สำหรับรายการที่มีองค์ประกอบทั้งหมดที่เป็นประเภทแฮช:

def gen_dupes(array):
    unique = {}
    for value in array:
        if value in unique and unique[value]:
            unique[value] = False
            yield value
        else:
            unique[value] = True

array = [1, 2, 2, 3, 4, 1, 5, 2, 6, 6]
print(list(gen_dupes(array)))
# => [2, 1, 6]

สำหรับรายการที่อาจมีรายการ:

def gen_dupes(array):
    unique = {}
    for value in array:
        is_list = False
        if type(value) is list:
            value = tuple(value)
            is_list = True

        if value in unique and unique[value]:
            unique[value] = False
            if is_list:
                value = list(value)

            yield value
        else:
            unique[value] = True

array = [1, 2, 2, [1, 2], 3, 4, [1, 2], 5, 2, 6, 6]
print(list(gen_dupes(array)))
# => [2, [1, 2], 6]

1
def removeduplicates(a):
  seen = set()

  for i in a:
    if i not in seen:
      seen.add(i)
  return seen 

print(removeduplicates([1,1,2,2]))

คุณส่งคืนชุดไม่ใช่รายการตามที่ร้องขอ ชุดประกอบด้วยองค์ประกอบที่ไม่ซ้ำกันเท่านั้นดังนั้นคำสั่ง if จึงไม่จำเป็นจริงๆ คุณควรอธิบายว่าอะไรคือข้อดีจากโซลูชันของคุณเมื่อเปรียบเทียบกับโซลูชันอื่น
Clemens


0

นี่คือวิธีที่ฉันต้องทำเพราะฉันท้าทายตัวเองไม่ให้ใช้วิธีอื่น:

def dupList(oldlist):
    if type(oldlist)==type((2,2)):
        oldlist=[x for x in oldlist]
    newList=[]
    newList=newList+oldlist
    oldlist=oldlist
    forbidden=[]
    checkPoint=0
    for i in range(len(oldlist)):
        #print 'start i', i
        if i in forbidden:
            continue
        else:
            for j in range(len(oldlist)):
                #print 'start j', j
                if j in forbidden:
                    continue
                else:
                    #print 'after Else'
                    if i!=j: 
                        #print 'i,j', i,j
                        #print oldlist
                        #print newList
                        if oldlist[j]==oldlist[i]:
                            #print 'oldlist[i],oldlist[j]', oldlist[i],oldlist[j]
                            forbidden.append(j)
                            #print 'forbidden', forbidden
                            del newList[j-checkPoint]
                            #print newList
                            checkPoint=checkPoint+1
    return newList

ตัวอย่างของคุณทำงานเป็น:

>>>a = [1,2,3,3,3,4,5,6,6,7]
>>>dupList(a)
[1, 2, 3, 4, 5, 6, 7]

3
นี่ไม่ใช่สิ่งที่ OP ต้องการ เขาต้องการรายการที่ซ้ำกันไม่ใช่รายการที่นำรายการที่ซ้ำกันออก duplist = list(set(a))ที่จะทำให้รายการที่มีรายการที่ซ้ำกันออกผมจะแนะนำ
zondo
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.