นี่เป็นคำถามเก่า แต่คำตอบบางอย่างที่ฉันเห็นโพสต์ไม่ได้ผลจริงเพราะzip
ไม่สามารถเขียนสคริปต์ได้ คำตอบอื่น ๆ ไม่ได้ใส่ใจimport operator
และให้ข้อมูลเพิ่มเติมเกี่ยวกับโมดูลนี้และประโยชน์ที่ได้รับที่นี่
มีสำนวนที่ดีอย่างน้อยสองประการสำหรับปัญหานี้ เริ่มต้นด้วยอินพุตตัวอย่างที่คุณให้ไว้:
X = ["a", "b", "c", "d", "e", "f", "g", "h", "i"]
Y = [ 0, 1, 1, 0, 1, 2, 2, 0, 1 ]
สิ่งนี้เป็นที่รู้จักกันในชื่อSchwartzian_transformหลังจากR. Schwartzซึ่งเป็นที่นิยมในรูปแบบนี้ใน Perl ใน 90s:
# Zip (decorate), sort and unzip (undecorate).
# Converting to list to script the output and extract X
list(zip(*(sorted(zip(Y,X)))))[1]
# Results in: ('a', 'd', 'h', 'b', 'c', 'e', 'i', 'f', 'g')
โปรดทราบว่าในกรณีนี้Y
และX
มีการจัดเรียงและเปรียบเทียบพจนานุกรม นั่นคือรายการแรก (จากY
) มีการเปรียบเทียบ; และหากเป็นเหมือนกันรายการที่สอง (จากX
) จะถูกเปรียบเทียบและอื่น ๆ สิ่งนี้สามารถสร้างความไม่แน่นอนเอาท์พุทที่เว้นแต่ว่าคุณได้รวมดัชนีรายการดั้งเดิมสำหรับการเรียงลำดับพจนานุกรมเพื่อให้ซ้ำกันในลำดับเดิม
สิ่งนี้ช่วยให้คุณควบคุมวิธีเรียงลำดับอินพุตได้โดยตรงมากขึ้นเพื่อให้คุณสามารถรับความเสถียรในการเรียงลำดับโดยเพียงระบุคีย์เฉพาะเพื่อเรียงลำดับ ดูตัวอย่างเพิ่มเติมที่นี่
import operator
# Sort by Y (1) and extract X [0]
list(zip(*sorted(zip(X,Y), key=operator.itemgetter(1))))[0]
# Results in: ('a', 'd', 'h', 'b', 'c', 'e', 'i', 'f', 'g')