วิธีจัดเรียงรายการสตริงตามตัวเลข?


128

ฉันรู้ว่ามันฟังดูไม่สำคัญ แต่ฉันไม่รู้ว่าsort()ฟังก์ชันของ Python นั้นแปลก ฉันมีรายการ "ตัวเลข" ที่อยู่ในรูปแบบสตริงดังนั้นฉันจึงแปลงเป็น ints ก่อนแล้วจึงลองเรียงลำดับ

list1=["1","10","3","22","23","4","2","200"]
for item in list1:
    item=int(item)

list1.sort()
print list1

ให้ฉัน:

['1', '10', '2', '200', '22', '23', '3', '4']

สิ่งที่ฉันต้องการคือ

['1','2','3','4','10','22','23','200']

ฉันได้มองหาอัลกอริทึมบางส่วนที่เกี่ยวข้องกับการเรียงชุดตัวเลข แต่สิ่งที่ฉันพบทั้งหมดเกี่ยวข้องกับการเรียงลำดับชุดตัวเลข

ฉันรู้ว่านี่อาจเป็นปัญหาง่ายๆ แต่ Google และหนังสือเรียนของฉันไม่ได้มีประโยชน์มากหรือน้อยไปกว่า.sort()ฟังก์ชันนี้


9
โปรดทราบว่า for loop ของคุณไม่ได้ทำในสิ่งที่ฉันสงสัยว่าคุณคิดว่าทำ
deinst

1
คุณไม่ได้อัปเดตในlist1เวลาใด อะไรทำให้คุณคิดว่าlistกำลังอัปเดต
ล็อต

ปัญหาที่คล้ายกันเพิ่มขึ้นเมื่อ list1 = ['1', '1.10', '1.11', '1.1', '1.2'] ถูกระบุเป็นอินพุต แทนที่จะได้ผลลัพธ์เป็น ['1', '1.1', '1.2', '1.10', '1.11'] ฉันได้รับ ['1', '1.1', '1.10', '1.11', '1.2' ]
sathish

2
ใน python 3 คุณอาจต้องการใช้sorted(mylist)
Akin Hwan

คำตอบ:


191

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

list1 = ["1","10","3","22","23","4","2","200"]
list1 = [int(x) for x in list1]
list1.sort()

หากด้วยเหตุผลบางประการคุณจำเป็นต้องเก็บสตริงไว้แทน ints (โดยปกติแล้วเป็นความคิดที่ไม่ดี แต่บางทีคุณอาจต้องเก็บเลขศูนย์นำหน้าหรืออะไรบางอย่าง) คุณสามารถใช้ฟังก์ชันหลักได้ sortรับพารามิเตอร์ที่มีชื่อkeyซึ่งเป็นฟังก์ชันที่เรียกใช้ในแต่ละองค์ประกอบก่อนที่จะเปรียบเทียบ ค่าส่งกลับของฟังก์ชันคีย์จะถูกเปรียบเทียบแทนการเปรียบเทียบองค์ประกอบรายการโดยตรง:

list1 = ["1","10","3","22","23","4","2","200"]
# call int(x) on each element before comparing it
list1.sort(key=int)

8
เมื่อฉันลองใช้ key = int ใน 2.7 ฉันไม่ได้รับ
KI4JGT

1
วิธีนี้ใช้งานได้หากองค์ประกอบรายการถูกจัดเก็บเป็น "จำนวนเต็ม" จะมีการจัดการอย่างไรในกรณีของค่าลอย เช่น list1 = [1, 1.10, 1.11, 1.1, 1.2]
sathish

1
@ KI4JGT วิธีการเรียงลำดับจะแก้ไขรายการและส่งคืน None ดังนั้นแทนที่จะlist1 = list1.sort(key=int)ใช้เพียงlist1.sort(key=int)และ list1 จะถูกจัดเรียงแล้ว
Josiah Yoder

1
@ KI4JGT .sort () เป็นตัวดำเนินการในสถานที่ซึ่งจะส่งกลับ None ซึ่งจะจัดเรียงรายการคุณอาจต้องการใช้
sorted

39

คุณสามารถผ่านฟังก์ชั่นให้กับkeyพารามิเตอร์วิธี ด้วยวิธีนี้ระบบจะจัดเรียงตามคีย์ (x) แทน x.sort

list1.sort(key=int)

BTW, การแปลงรายการเพื่อจำนวนเต็มถาวรใช้ฟังก์ชั่นmap

list1 = list(map(int, list1))   # you don't need to call list() in Python 2.x

หรือรายการความเข้าใจ

list1 = [int(x) for x in list1]

21

ในกรณีที่คุณต้องการใช้sorted()ฟังก์ชัน:sorted(list1, key=int)

ส่งคืนรายการที่จัดเรียงใหม่


1
ใช้ได้กับชุดด้วย!
MT

12

การเรียงลำดับของ Python ไม่ใช่เรื่องแปลก เป็นเพียงรหัสนี้:

for item in list1:
   item=int(item)

ไม่ได้ทำในสิ่งที่คุณคิด - itemไม่ได้ถูกแทนที่กลับเข้าไปในรายการมันถูกโยนทิ้งไป

อย่างไรก็ตามวิธีแก้ปัญหาที่ถูกต้องคือใช้key=intตามที่คนอื่นแสดงให้คุณเห็น


12

คุณยังสามารถใช้:

import re

def sort_human(l):
    convert = lambda text: float(text) if text.isdigit() else text
    alphanum = lambda key: [convert(c) for c in re.split('([-+]?[0-9]*\.?[0-9]*)', key)]
    l.sort(key=alphanum)
    return l

นี้จะคล้ายกับสิ่งอื่น ๆ ที่คุณสามารถค้นหาบนอินเทอร์เน็ต แต่ยังสามารถใช้ได้กับ alphanumericals [abc0.1, abc0.2, ...]เช่น


9

เมื่อวานนี้ฉันพบปัญหาเดียวกันและพบโมดูลชื่อ [natsort] [1] ซึ่งช่วยแก้ปัญหาของคุณได้ ใช้:

from natsort import natsorted # pip install natsort

# Example list of strings
a = ['1', '10', '2', '3', '11']

[In]  sorted(a)
[Out] ['1', '10', '11', '2', '3']

[In]  natsorted(a)
[Out] ['1', '2', '3', '10', '11']

# Your array may contain strings
[In]  natsorted(['string11', 'string3', 'string1', 'string10', 'string100'])
[Out] ['string1', 'string3', 'string10', 'string11', 'string100']

นอกจากนี้ยังใช้กับพจนานุกรมได้เทียบเท่ากับsorted. [1]: https://pypi.org/project/natsort/



3

ลองทำเช่นนี้โดยจะจัดเรียงรายการในตำแหน่งจากมากไปหาน้อย (ไม่จำเป็นต้องระบุคีย์ในกรณีนี้):

กระบวนการ

listB = [24, 13, -15, -36, 8, 22, 48, 25, 46, -9]
listC = sorted(listB, reverse=True) # listB remains untouched
print listC

เอาท์พุท:

 [48, 46, 25, 24, 22, 13, 8, -9, -15, -36]

0

วิธีแก้ปัญหาล่าสุดถูกต้อง คุณกำลังอ่านคำตอบเป็นสตริงซึ่งในกรณีนี้ลำดับคือ 1 จากนั้น 100 แล้ว 104 ตามด้วย 2 แล้ว 21 จากนั้น 2001001010, 3 และอื่น ๆ

คุณต้องแคสต์อินพุตของคุณเป็น int แทน:

สตริงที่จัดเรียง:

stringList = (1, 10, 2, 21, 3)

ints ที่จัดเรียง:

intList = (1, 2, 3, 10, 21)

ในการแคสต์ให้ใส่ stringList ไว้ใน int (blahblah)

อีกครั้ง:

stringList = (1, 10, 2, 21, 3)

newList = int (stringList)

print newList

=> returns (1, 2, 3, 10, 21) 

1
TypeError: int () อาร์กิวเมนต์ต้องเป็นสตริงหรือตัวเลขไม่ใช่ 'tuple'
Cees Timmerman

นอกจากนี้สตริงใน stringList ของคุณควรมีเครื่องหมายคำพูด
Teepeemm

2
นั่นเป็นการทำนายของ helluva ที่จะทำให้: "ทางออกล่าสุดถูกต้อง";)
GreenAsJade

0

หากคุณต้องการใช้สตริงของตัวเลขให้ใช้รายการอื่นตามที่แสดงในรหัสของฉันมันจะทำงานได้ดี

list1=["1","10","3","22","23","4","2","200"]

k=[]    
for item in list1:    
    k.append(int(item))

k.sort()
print(k)
# [1, 2, 3, 4, 10, 22, 23, 200]

0

วิธีง่ายๆในการจัดเรียงรายการตัวเลข

numlists = ["5","50","7","51","87","97","53"]
results = list(map(int, numlists))
results.sort(reverse=False)
print(results)

-1

ปัญหาที่แท้จริงคือการเรียงลำดับสิ่งต่างๆตามตัวอักษรและตัวเลข ดังนั้นหากคุณมีรายการ ['1', '2', '10', '19'] และเรียกใช้การจัดเรียงคุณจะได้รับ ['1', '10' '19', '2'] เช่น 10 มาก่อน 2 เพราะดูที่อักขระตัวแรกและเรียงลำดับโดยเริ่มจากนั้น ดูเหมือนว่าวิธีการส่วนใหญ่ใน python จะส่งคืนสิ่งต่างๆตามลำดับนั้น ตัวอย่างเช่นหากคุณมีไดเร็กทอรีชื่อ abc โดยมีไฟล์ชื่อ 1.jpg, 2.jpg และอื่น ๆ พูดได้ถึง 15.jpg และคุณทำ file_list = os.listdir (abc) file_list จะไม่เรียงลำดับตามที่คุณคาดหวัง แต่จะเป็น file_list = ['1.jpg', '11 .jpg '---' 15.jpg ',' 2.jpg] หากลำดับการประมวลผลไฟล์มีความสำคัญ (น่าจะเป็นสาเหตุที่คุณตั้งชื่อไฟล์ตามตัวเลข) ลำดับไม่ใช่สิ่งที่คุณคิดว่าจะเป็น คุณสามารถหลีกเลี่ยงปัญหานี้ได้โดยใช้ช่องว่างภายใน "ศูนย์" ตัวอย่างเช่นหากคุณมี list alist = ['01', '03', '05', '10', '02', '04', '06] และคุณจัดเรียงตามลำดับคุณจะได้ลำดับที่คุณต้องการ alist = ['01', '02' ฯลฯ ] เนื่องจากอักขระตัวแรกคือ 0 ซึ่งมาก่อน 1 จำนวนช่องว่างของศูนย์ที่คุณต้องการจะถูกกำหนดโดยค่าที่ใหญ่ที่สุดในรายการตัวอย่างเช่นถ้าค่าที่ใหญ่ที่สุดพูดระหว่าง 100 ถึง 1,000 คุณต้องใส่ตัวเลขหลักเดียวเช่น 001, 002 - 010,011--100, 101 เป็นต้น


-5
scores = ['91','89','87','86','85']
scores.sort()
print (scores)

สิ่งนี้ใช้ได้กับฉันโดยใช้ python เวอร์ชัน 3 แม้ว่าจะไม่ได้อยู่ในเวอร์ชัน 2 ก็ตาม


3
ลองจัดเรียงด้วย '11 และ '100' ที่นั่นเมื่อสิ่งต่างๆน่าสนใจ
Penz
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.