ตรวจสอบว่าองค์ประกอบทั้งหมดในรายการเหมือนกันหรือไม่


389

ฉันต้องการฟังก์ชั่นต่อไปนี้:

อินพุต :list

ผลผลิต :

  • True หากองค์ประกอบทั้งหมดในรายการอินพุตประเมินผลเท่ากันโดยใช้ตัวดำเนินการความเสมอภาคมาตรฐาน
  • False มิฉะนั้น.

ประสิทธิภาพ : แน่นอนฉันไม่ต้องการให้เกิดค่าใช้จ่ายที่ไม่จำเป็น

ฉันรู้สึกว่ามันจะดีที่สุด:

  • วนซ้ำตามรายการ
  • เปรียบเทียบองค์ประกอบที่อยู่ติดกัน
  • และANDค่าบูลีนผลลัพธ์ทั้งหมด

แต่ฉันไม่แน่ใจว่าเป็นวิธีที่ Pythonic ที่สุดที่จะทำ


การขาดคุณสมบัติลัดวงจรเพียงเจ็บอินพุตยาว (มากกว่า ~ 50 องค์ประกอบ) ที่มีองค์ประกอบที่ไม่เท่ากันในช่วงต้น หากสิ่งนี้เกิดขึ้นบ่อยครั้งเพียงพอ (ความถี่ขึ้นอยู่กับจำนวนรายการที่อาจจะเกิดขึ้น) จำเป็นต้องใช้ไฟฟ้าลัดวงจร ขั้นตอนวิธีการลัดวงจรที่ดีที่สุดน่าจะเป็น checkEqual1@KennyTM อย่างไรก็ตามมันจ่ายค่าใช้จ่ายที่สำคัญสำหรับสิ่งนี้:

  • มากถึง 20x ในรายการที่เกือบเหมือนประสิทธิภาพ
  • ประสิทธิภาพสูงสุด 2.5x สำหรับรายการสั้น ๆ

หากอินพุตยาวที่มีองค์ประกอบไม่เท่ากันต้นไม่เกิดขึ้น (หรือเกิดขึ้นน้อยมาก) ไม่จำเป็นต้องใช้ไฟฟ้าลัดวงจร จากนั้นที่เร็วที่สุดคือโซลูชันของ @Ivo van der Wijk


3
เท่ากับเป็นในa == bหรือเหมือนกันในขณะที่a is b?
kennytm

1
วิธีแก้ปัญหาควรจัดการกับรายการที่ว่างเปล่า? ถ้าเป็นเช่นนั้นสิ่งที่ควรส่งคืน
Doug

1
เท่ากับใน a == b ควรจัดการรายการที่ว่างเปล่าและส่งคืน True
สูงสุด

2
แม้ว่าฉันจะรู้ว่าช้ากว่าคำแนะนำอื่น ๆ แต่ฉันก็functools.reduce(operator.eq, a)ยังไม่ได้รับคำแนะนำ
2846495

คำตอบ:


420

วิธีการทั่วไป:

def checkEqual1(iterator):
    iterator = iter(iterator)
    try:
        first = next(iterator)
    except StopIteration:
        return True
    return all(first == rest for rest in iterator)

หนึ่งในสายการบิน:

def checkEqual2(iterator):
   return len(set(iterator)) <= 1

อีกหนึ่งซับ:

def checkEqual3(lst):
   return lst[1:] == lst[:-1]

ความแตกต่างระหว่าง 3 เวอร์ชันคือ:

  1. ในcheckEqual2เนื้อหาจะต้องแฮช
  2. checkEqual1และcheckEqual2สามารถใช้ตัววนซ้ำใด ๆ ได้ แต่checkEqual3ต้องป้อนลำดับตามลำดับโดยทั่วไปแล้วจะเป็นคอนเทนเนอร์คอนกรีตเช่นรายการหรือทูเปิล
  3. checkEqual1 หยุดทันทีที่พบความแตกต่าง
  4. เนื่องจากcheckEqual1มีรหัส Python มากกว่าจึงมีประสิทธิภาพน้อยกว่าเมื่อมีหลายรายการที่เท่ากันในตอนเริ่มต้น
  5. เนื่องจากcheckEqual2และcheckEqual3ดำเนินการคัดลอก O (N) เสมอพวกเขาจะใช้เวลานานขึ้นหากข้อมูลส่วนใหญ่ของคุณจะส่งกลับค่าเท็จ
  6. สำหรับcheckEqual2และcheckEqual3มันเป็นเรื่องยากที่จะปรับตัวเข้ากับการเปรียบเทียบจากไปa == ba is b

timeit ผลลัพธ์สำหรับ Python 2.7 และ (เฉพาะ s1, s4, s7, s9 ควรกลับ True)

s1 = [1] * 5000
s2 = [1] * 4999 + [2]
s3 = [2] + [1]*4999
s4 = [set([9])] * 5000
s5 = [set([9])] * 4999 + [set([10])]
s6 = [set([10])] + [set([9])] * 4999
s7 = [1,1]
s8 = [1,2]
s9 = []

เราได้รับ

      | checkEqual1 | checkEqual2 | checkEqual3  | checkEqualIvo | checkEqual6502 |
|-----|-------------|-------------|--------------|---------------|----------------|
| s1  | 1.19   msec | 348    usec | 183     usec | 51.6    usec  | 121     usec   |
| s2  | 1.17   msec | 376    usec | 185     usec | 50.9    usec  | 118     usec   |
| s3  | 4.17   usec | 348    usec | 120     usec | 264     usec  | 61.3    usec   |
|     |             |             |              |               |                |
| s4  | 1.73   msec |             | 182     usec | 50.5    usec  | 121     usec   |
| s5  | 1.71   msec |             | 181     usec | 50.6    usec  | 125     usec   |
| s6  | 4.29   usec |             | 122     usec | 423     usec  | 61.1    usec   |
|     |             |             |              |               |                |
| s7  | 3.1    usec | 1.4    usec | 1.24    usec | 0.932   usec  | 1.92    usec   |
| s8  | 4.07   usec | 1.54   usec | 1.28    usec | 0.997   usec  | 1.79    usec   |
| s9  | 5.91   usec | 1.25   usec | 0.749   usec | 0.407   usec  | 0.386   usec   |

บันทึก:

# http://stackoverflow.com/q/3844948/
def checkEqualIvo(lst):
    return not lst or lst.count(lst[0]) == len(lst)

# http://stackoverflow.com/q/3844931/
def checkEqual6502(lst):
    return not lst or [lst[0]]*len(lst) == lst

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

7
@max: ใช่ โปรดทราบว่า 1 msec = 1,000 usec
kennytm

1
อย่าลืมการวิเคราะห์การใช้หน่วยความจำสำหรับอาร์เรย์ที่มีขนาดใหญ่มากโซลูชั่นแบบเนทีฟที่ปรับการโทรออกไปเป็นobj.__eq__เวลาlhs is rhsและการปรับให้เหมาะสมแบบไม่เป็นไปตามลำดับ
Glenn Maynard

3
Ivo van der Wijk มีทางออกที่ดีกว่าสำหรับลำดับที่เร็วกว่าการตั้งค่าประมาณ 5 เท่าและ O (1) ในหน่วยความจำ
aaronasterling

2
นอกจากนี้ยังมีitertoolsสูตรที่ฉันได้เพิ่มไว้เป็นคำตอบ มันอาจคุ้มค่าที่จะโยนมันลงในตารางเวลาของคุณ :-)
mgilson

298

วิธีแก้ปัญหาที่เร็วกว่าการใช้ set () ที่ทำงานกับลำดับ (ไม่ใช่ iterables) คือการนับองค์ประกอบแรก นี่ถือว่าเป็นรายการที่ไม่ว่างเปล่า (แต่มันไม่ค่อยสำคัญในการตรวจสอบและตัดสินใจด้วยตัวเองว่าผลลัพธ์ควรอยู่ในรายการที่ว่างเปล่า)

x.count(x[0]) == len(x)

มาตรฐานง่ายๆ:

>>> timeit.timeit('len(set(s1))<=1', 's1=[1]*5000', number=10000)
1.4383411407470703
>>> timeit.timeit('len(set(s1))<=1', 's1=[1]*4999+[2]', number=10000)
1.4765670299530029
>>> timeit.timeit('s1.count(s1[0])==len(s1)', 's1=[1]*5000', number=10000)
0.26274609565734863
>>> timeit.timeit('s1.count(s1[0])==len(s1)', 's1=[1]*4999+[2]', number=10000)
0.25654196739196777

5
OMG เร็วกว่าชุดโซลูชั่นถึง 6 เท่า! (280 ล้านชิ้น / วินาทีเทียบกับ 45 ล้านชิ้น / วินาทีบนแล็ปท็อปของฉัน) ทำไม??? และมีวิธีใดที่จะแก้ไขเพื่อให้วงจรสั้น (ฉันเดาไม่ได้ ... )
สูงสุด

2
ฉันเดา list.count มีการติดตั้ง C ที่เหมาะสมที่สุดและความยาวของรายการจะถูกเก็บไว้ภายในดังนั้น len () จึงมีราคาถูกเช่นกัน ไม่มีวิธีนับจำนวนลัดวงจร () เนื่องจากคุณจะต้องตรวจสอบองค์ประกอบทั้งหมดเพื่อให้ได้จำนวนที่ถูกต้อง
Ivo van der Wijk

ฉันสามารถเปลี่ยนเป็น: x.count(next(x)) == len(x)เพื่อใช้งานกับคอนเทนเนอร์ x ใด ๆ ได้หรือไม่ อืม .. เห็นแล้วว่า. จำนวนใช้ได้เฉพาะกับซีเควนเชียล .. ทำไมจึงไม่ใช้กับคอนเทนเนอร์บิวด์อินอื่น การนับในพจนานุกรมมีความหมายน้อยกว่าในรายการหรือไม่
สูงสุด

4
ตัววนซ้ำอาจมีความยาวไม่ได้ เช่นมันสามารถไม่มีที่สิ้นสุดหรือสร้างขึ้นแบบไดนามิก คุณสามารถค้นหาความยาวของมันได้ด้วยการแปลงให้เป็นรายการที่ใช้ประโยชน์จาก iterators ส่วนใหญ่
Ivo van der Wijk

ขออภัยสิ่งที่ฉันหมายถึงคือสาเหตุที่countไม่มีการใช้งานสำหรับ iterables ไม่ใช่เพราะเหตุใดจึงlenไม่พร้อมใช้งานสำหรับ iterators คำตอบน่าจะเป็นเพียงการกำกับดูแล แต่มันไม่เกี่ยวข้องสำหรับเราเพราะค่าเริ่มต้น.count()สำหรับลำดับช้ามาก (pure python) เหตุผลการแก้ปัญหาของคุณเป็นอย่างรวดเร็วก็คือว่ามันอาศัยอยู่กับ C-ซึ่งสร้างให้โดยcount listดังนั้นฉันคิดว่าสิ่งใดที่เกิดขึ้นเพื่อใช้countวิธีการใน C จะได้ประโยชน์จากวิธีการของคุณ
สูงสุด

164

วิธีที่ง่ายที่สุดและหรูหราที่สุดมีดังนี้:

all(x==myList[0] for x in myList)

(ใช่มันใช้กับรายการที่ว่างได้ด้วย! นี่เป็นเพราะหนึ่งในไม่กี่กรณีที่ไพ ธ อนมีความหมายแบบขี้เกียจ)

เกี่ยวกับประสิทธิภาพการทำงานสิ่งนี้จะล้มเหลวในเวลาที่เร็วที่สุดดังนั้นจึงเป็นวิธีที่เหมาะสมที่สุด


งานนี้ แต่มันเป็นบิต (1.5 เท่า) ช้ากว่า checkEqual1@KennyTM ฉันไม่แน่ใจว่าทำไม
สูงสุด

4
สูงสุด: น่าจะเพราะผมไม่ได้รำคาญที่จะดำเนินการเพิ่มประสิทธิภาพfirst=myList[0] all(x==first for x in myList)บางที
ninjagecko

ฉันคิดว่า myList [0] ถูกประเมินด้วยการวนซ้ำแต่ละครั้ง >>> timeit.timeit ('ทั้งหมด ([y == x [0] สำหรับ y ใน x])', 'x = [1] * 4000', จำนวน = 10,000) 2.707076672740641 >>> timeit.timeit ('x0 = x [0]; ทั้งหมด ([y == x0 สำหรับ y ใน x]) ',' x = [1] * 4000 ', จำนวน = 10,000) 2.0908854261426484
Matt Liberty

1
แน่นอนฉันควรชี้แจงว่าการเพิ่มประสิทธิภาพfirst=myList[0]จะโยนIndexErrorในรายการว่างดังนั้นผู้แสดงความคิดเห็นที่พูดถึงการเพิ่มประสิทธิภาพที่ฉันกล่าวถึงจะต้องจัดการกับกรณีขอบของรายการที่ว่างเปล่า อย่างไรก็ตามต้นฉบับไม่เป็นไร (ใช้ได้x==myList[0]ภายในallเพราะไม่เคยถูกประเมินถ้ารายการว่างเปล่า)
ninjagecko

1
นี่เป็นวิธีที่เหมาะสมอย่างชัดเจน หากคุณต้องการความเร็วในทุกกรณีให้ใช้บางอย่างที่ไม่ต้องการ
Henry Gomersall

45

การเปรียบเทียบชุดทำงาน:

len(set(the_list)) == 1

การใช้setจะลบองค์ประกอบที่ซ้ำกันทั้งหมด


26

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

if len(sets.Set(input_list)) == 1
// input_list has all identical elements.

นี่เป็นสิ่งที่ดี แต่มันไม่ลัดวงจรและคุณต้องคำนวณความยาวของรายการผลลัพธ์
aaronasterling

15
ทำไมไม่เพียงlen(set(input_list)) == 1?
Nick Dandoulakis

2
@codaddict หมายความว่าแม้ว่าองค์ประกอบสองรายการแรกนั้นจะแตกต่างกัน แต่ก็ยังคงทำการค้นหาทั้งหมด มันยังใช้พื้นที่พิเศษ O (k) โดยที่ k คือจำนวนองค์ประกอบที่แตกต่างในรายการ
aaronasterling

1
@max เนื่องจากการสร้างชุดเกิดขึ้นใน C และคุณมีการใช้งานที่ไม่ดี อย่างน้อยคุณควรทำในนิพจน์ตัวสร้าง ดูคำตอบของ KennyTM สำหรับวิธีการทำอย่างถูกต้องโดยไม่ต้องใช้ชุด
aaronasterling

1
sets.Set คือ "เลิกใช้แล้วตั้งแต่เวอร์ชัน 2.6: ชนิด set-frozenet ในตัวแทนที่โมดูลนี้" (จากdocs.python.org/2/library/sets.html )
Moberg

21

สำหรับสิ่งที่คุ้มค่านี้ขึ้นมาบนหลามความคิดรายการจดหมายเมื่อเร็ว ๆ นี้ ปรากฎว่ามีสูตร itertoolsสำหรับทำสิ่งนี้อยู่แล้ว: 1

def all_equal(iterable):
    "Returns True if all the elements are equal to each other"
    g = groupby(iterable)
    return next(g, True) and not next(g, False)

สมมุติว่ามันทำงานได้ดีมากและมีคุณสมบัติที่ดีไม่กี่

  1. ลัดวงจร: มันจะหยุดการบริโภคไอเท็มจาก iterable ทันทีที่พบไอเท็มแรกที่ไม่เท่ากัน
  2. ไม่ต้องใช้รายการที่จะแฮช
  3. มันขี้เกียจและต้องการเพียง O (1) หน่วยความจำเพิ่มเติมเพื่อทำการตรวจสอบ

1กล่าวอีกนัยหนึ่งฉันไม่สามารถใช้เครดิตในการแก้ปัญหาได้ - ฉันจะไม่สามารถนำเครดิตไปใช้เพื่อค้นหาได้


3
เร็วกว่าคำตอบที่เร็วที่สุดที่ระบุไว้ที่นี่ในสถานการณ์กรณีที่เลวร้ายที่สุด
ChaimG

return next(g, f := next(g, g)) == f(จาก py3.8 แน่นอน)
Chris_Rands

17

ต่อไปนี้เป็นวิธีการง่ายๆสองวิธี

ใช้ชุด ()

เมื่อแปลงรายการเป็นชุดองค์ประกอบที่ซ้ำกันจะถูกลบออก ดังนั้นหากความยาวของชุดแปลงเป็น 1 แล้วนี่ก็หมายความว่าองค์ประกอบทั้งหมดจะเหมือนกัน

len(set(input_list))==1

นี่คือตัวอย่าง

>>> a = ['not', 'the', 'same']
>>> b = ['same', 'same', 'same']
>>> len(set(a))==1  # == 3
False
>>> len(set(b))==1  # == 1
True

ใช้ทั้งหมด ()

สิ่งนี้จะทำการเปรียบเทียบ (เทียบเท่า) องค์ประกอบแรกของรายการอินพุตกับองค์ประกอบอื่น ๆ ในรายการ หากทั้งหมดเท่ากับ True จะถูกส่งคืนมิฉะนั้น False จะถูกส่งคืน

all(element==input_list[0] for element in input_list)

นี่คือตัวอย่าง

>>> a = [1, 2, 3, 4, 5]
>>> b = [1, 1, 1, 1, 1]
>>> all(number==a[0] for number in a)
False
>>> all(number==b[0] for number in b)
True

PS หากคุณกำลังตรวจสอบเพื่อดูว่ารายการทั้งหมดเทียบเท่ากับค่าที่แน่นอนคุณสามารถใช้ค่าสำหรับ input_list [0]


1
สำหรับผู้ที่สนใจเรื่อง runtime การแสดงlen(set(a))รายการ 10,000,000 องค์ประกอบใช้เวลา 0.09 วินาทีในขณะที่การแสดงนั้นallใช้เวลา 0.9 วินาที (นานกว่า 10 เท่า)
Elliptica

2
ฉันชอบคำตอบนี้สำหรับความเรียบง่ายแบบ pythonic นอกเหนือจากคะแนนประสิทธิภาพที่กล่าวถึงโดย @Elliptica
NickBraunagel

11

นี่คือตัวเลือกอื่นเร็วกว่าlen(set(x))==1สำหรับรายการยาว (ใช้ไฟฟ้าลัดวงจร)

def constantList(x):
    return x and [x[0]]*len(x) == x

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

9

นี่เป็นวิธีง่ายๆในการทำ:

result = mylist and all(mylist[0] == elem for elem in mylist)

สิ่งนี้ซับซ้อนกว่าเล็กน้อยมันมีค่าใช้จ่ายในการเรียกใช้ฟังก์ชั่น แต่ความหมายชัดเจนกว่า:

def all_identical(seq):
    if not seq:
        # empty list is False.
        return False
    first = seq[0]
    return all(first == elem for elem in seq)

for elem in mylist[1:]คุณสามารถหลีกเลี่ยงการเปรียบเทียบซ้ำซ้อนที่นี่โดยใช้ ไม่ต้องสงสัยเลยว่ามันจะช่วยเพิ่มความเร็วได้มาก แต่เนื่องจากฉันเดาว่าelem[0] is elem[0]ล่ามอาจจะทำการเปรียบเทียบนั้นได้อย่างรวดเร็ว
เบรนแดน

5

ตรวจสอบว่าองค์ประกอบทั้งหมดเท่ากับแรก

np.allclose(array, array[0])


ต้องการโมดูลของบุคคลที่สาม
Bachsau

4

ข้อสงสัยนี้เป็น "Pythonic ที่สุด" แต่สิ่งที่ชอบ:

>>> falseList = [1,2,3,4]
>>> trueList = [1, 1, 1]
>>> 
>>> def testList(list):
...   for item in list[1:]:
...     if item != list[0]:
...       return False
...   return True
... 
>>> testList(falseList)
False
>>> testList(trueList)
True

จะทำเคล็ดลับ


1
การforวนซ้ำของคุณสามารถทำให้ Pythonic if any(item != list[0] for item in list[1:]): return Falseมีความหมายเหมือนกันมากขึ้น
musiphil

4

หากคุณสนใจในบางสิ่งที่สามารถอ่านได้มากกว่า (แต่ไม่ได้ผลมากนัก) คุณสามารถลอง:

def compare_lists(list1, list2):
    if len(list1) != len(list2): # Weed out unequal length lists.
        return False
    for item in list1:
        if item not in list2:
            return False
    return True

a_list_1 = ['apple', 'orange', 'grape', 'pear']
a_list_2 = ['pear', 'orange', 'grape', 'apple']

b_list_1 = ['apple', 'orange', 'grape', 'pear']
b_list_2 = ['apple', 'orange', 'banana', 'pear']

c_list_1 = ['apple', 'orange', 'grape']
c_list_2 = ['grape', 'orange']

print compare_lists(a_list_1, a_list_2) # Returns True
print compare_lists(b_list_1, b_list_2) # Returns False
print compare_lists(c_list_1, c_list_2) # Returns False

ฉันพยายามที่จะดูว่าองค์ประกอบทั้งหมดในรายการเดียวเหมือนกันหรือไม่ ไม่ใช่ถ้าสองรายการแยกกันเหมือนกัน
สูงสุด

4

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

list1 = [1,1,1]
len(set(list1)) 
>1

list1 = [1,2,3]
len(set(list1)
>3

4

เกี่ยวกับการใช้กับreduce() lambdaนี่คือรหัสการทำงานที่ฉันคิดว่าเป็นวิธีที่ดีกว่าคำตอบอื่น ๆ

reduce(lambda x, y: (x[1]==y, y), [2, 2, 2], (True, 2))

ส่งคืน tuple โดยที่ค่าแรกเป็นบูลีนหากทุกรายการเหมือนกันหรือไม่


มีข้อผิดพลาดเล็กน้อยในรหัสตามที่เขียนไว้ (ลอง[1, 2, 2]): จะไม่นำค่าบูลีนก่อนหน้ามาพิจารณา นี้สามารถแก้ไขได้โดยการแทนที่ด้วยx[1] == y x[0] and x[1] == y
schot

3

ฉันจะทำ:

not any((x[i] != x[i+1] for i in range(0, len(x)-1)))

เป็นanyหยุดค้นหา iterable เร็วที่สุดเท่าที่จะพบTrueสภาพ


คุณไม่จำเป็นต้องใส่วงเล็บเสริมรอบ ๆ นิพจน์ตัวสร้างหากเป็นอาร์กิวเมนต์เท่านั้น
ninjagecko

ดังนั้นall()ทำไมไม่ใช้all(x == seq[0] for x in seq)? ดูไพเราะมากขึ้นและควรทำแบบเดียวกัน
Chen A.

2
>>> a = [1, 2, 3, 4, 5, 6]
>>> z = [(a[x], a[x+1]) for x in range(0, len(a)-1)]
>>> z
[(1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]
# Replacing it with the test
>>> z = [(a[x] == a[x+1]) for x in range(0, len(a)-1)]
>>> z
[False, False, False, False, False]
>>> if False in z : Print "All elements are not equal"

2
def allTheSame(i):
    j = itertools.groupby(i)
    for k in j: break
    for k in j: return False
    return True

ใช้งานได้ใน Python 2.4 ซึ่งไม่มี "ทั้งหมด"


1
for k in j: breaknext(j)เทียบเท่ากับ คุณสามารถทำได้def allTheSame(x): return len(list(itertools.groupby(x))<2)ถ้าคุณไม่ใส่ใจเรื่องประสิทธิภาพ
ninjagecko


2

หรือใช้diffวิธีการ numpy:

import numpy as np
def allthesame(l):
    return np.all(np.diff(l)==0)

และโทร:

print(allthesame([1,1,1]))

เอาท์พุท:

True

ฉันคิดว่าnot np.any(np.diff(l))อาจเร็วกว่านี้สักหน่อย
GZ0

2

หรือใช้วิธี diff ของ numpy:

import numpy as np
def allthesame(l):
    return np.unique(l).shape[0]<=1

และโทร:

print(allthesame([1,1,1]))

เอาท์พุท:

จริง


คำตอบนี้เหมือนกับคำตอบจาก U9-Forward จากปีที่แล้ว
mhwombat

ตาดี! ฉันใช้โครงสร้าง / API เดียวกัน แต่วิธีการของฉันใช้ np.unique และรูปร่าง ฟังก์ชั่นของ U9 ใช้ np.all () และ np.diff () - ฉันไม่ได้ใช้ฟังก์ชั่นเหล่านั้น
Luis B

1

คุณทำได้:

reduce(and_, (x==yourList[0] for x in yourList), True)

มันค่อนข้างน่ารำคาญที่หลามทำให้คุณนำเข้าตัวดำเนินการเช่นoperator.and_นั้น ตั้งแต่ python3 คุณจะต้องนำเข้าfunctools.reduceด้วย

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


นี่จะไม่ลัดวงจร ทำไมคุณถึงชอบมากกว่าโซลูชันอื่น ๆ ของคุณ?
สูงสุด

@max: คุณจะไม่แม่นยำด้วยเหตุผลนั้น ฉันรวมมันเพื่อความสมบูรณ์ ฉันควรจะแก้ไขเพื่อพูดถึงว่าขอบคุณ
ninjagecko

1
lambda lst: reduce(lambda a,b:(b,b==a[0] and a[1]), lst, (lst[0], True))[1]

อันถัดไปจะลัดวงจร:

all(itertools.imap(lambda i:yourlist[i]==yourlist[i+1], xrange(len(yourlist)-1)))

รหัสแรกของคุณเป็นความผิดพลาดอย่างเห็นได้ชัด: reduce(lambda a,b:a==b, [2,2,2])อัตราผลตอบแทนFalse... ฉันแก้ไขมัน แต่วิธีนี้จะไม่สวยอีกต่อไป
berdario

@berdario คุณควรเขียนคำตอบของคุณเองแทนที่จะเปลี่ยนสิ่งที่คนอื่นเขียน หากคุณคิดว่าคำตอบนี้ผิดคุณสามารถแสดงความคิดเห็นได้และ / หรือลดระดับลง
Gorpik

3
ดีกว่าที่จะแก้ไขสิ่งที่ผิดพลาดกว่าปล่อยให้ผู้คนอ่านมันอาจจะพลาดความคิดเห็นที่อธิบายว่าทำไมมันถึงผิด
berdario

3
"ฉันควรแก้ไขบทความเมื่อใด" "เมื่อใดก็ตามที่คุณรู้สึกว่าคุณสามารถโพสต์ได้ดีขึ้นและมีแนวโน้มที่จะทำเช่นนั้นการแก้ไขได้รับการสนับสนุน!"
berdario

1

เปลี่ยนรายการเป็นชุด จากนั้นถ้าขนาดของชุดเป็นเพียง 1 พวกเขาจะต้องได้รับเหมือนกัน

if len(set(my_list)) == 1:

1

นอกจากนี้ยังมีตัวเลือกการเรียกซ้ำ Python แท้:

 def checkEqual(lst):
    if len(lst)==2 :
        return lst[0]==lst[1]
    else:
        return lst[0]==lst[1] and checkEqual(lst[1:])

อย่างไรก็ตามด้วยเหตุผลบางอย่างมันเป็นในบางกรณีสองคำสั่งของขนาดที่ช้ากว่าตัวเลือกอื่น ๆ มาจากความคิดทางภาษา C ฉันคาดว่าสิ่งนี้จะเร็วขึ้น แต่ก็ไม่ได้!

ข้อเสียอื่น ๆ คือมีการ จำกัด การเรียกซ้ำใน Python ซึ่งจำเป็นต้องปรับในกรณีนี้ ยกตัวอย่างเช่นการใช้นี้


0

คุณสามารถใช้.nunique()เพื่อค้นหาจำนวนรายการที่ไม่ซ้ำกันในรายการ

def identical_elements(list):
    series = pd.Series(list)
    if series.nunique() == 1: identical = True
    else:  identical = False
    return identical



identical_elements(['a', 'a'])
Out[427]: True

identical_elements(['a', 'b'])
Out[428]: False

0

setคุณสามารถใช้ มันจะทำให้การตั้งค่าและลบองค์ประกอบซ้ำ จากนั้นตรวจสอบว่ามีองค์ประกอบไม่เกิน 1 รายการ

if len(set(your_list)) <= 1:
    print('all ements are equal')

ตัวอย่าง:

>>> len(set([5, 5])) <= 1
True
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.