ฉันมีรายการเช่นด้านล่างที่องค์ประกอบแรกคือ ID และอื่น ๆ ที่เป็นสตริง:
[(1, u'abc'), (2, u'def')]
ฉันต้องการสร้างรายการของรหัสจากรายการของ tuples เท่านั้นด้านล่าง:
[1,2]
ฉันจะใช้รายการนี้__in
ดังนั้นจึงจำเป็นต้องเป็นรายการค่าจำนวนเต็ม
ฉันมีรายการเช่นด้านล่างที่องค์ประกอบแรกคือ ID และอื่น ๆ ที่เป็นสตริง:
[(1, u'abc'), (2, u'def')]
ฉันต้องการสร้างรายการของรหัสจากรายการของ tuples เท่านั้นด้านล่าง:
[1,2]
ฉันจะใช้รายการนี้__in
ดังนั้นจึงจำเป็นต้องเป็นรายการค่าจำนวนเต็ม
คำตอบ:
>>> a = [(1, u'abc'), (2, u'def')]
>>> [i[0] for i in a]
[1, 2]
ใช้ฟังก์ชั่นซิปเพื่อแยกองค์ประกอบ:
>>> inpt = [(1, u'abc'), (2, u'def')]
>>> unzipped = zip(*inpt)
>>> print unzipped
[(1, 2), (u'abc', u'def')]
>>> print list(unzipped[0])
[1, 2]
แก้ไข (@BradSolomon): การทำงานด้านบนสำหรับ Python 2.x โดยที่zip
ส่งคืนรายการ
ใน Python 3.x ให้zip
ผลตอบแทนเป็นตัววนซ้ำและสิ่งต่อไปนี้จะเทียบเท่ากับด้านบน:
>>> print(list(list(zip(*inpt))[0]))
[1, 2]
คุณหมายถึงอะไรเช่นนี้
new_list = [ seq[0] for seq in yourlist ]
สิ่งที่คุณมีคือรายการtuple
วัตถุไม่ใช่รายการชุด (ตามคำถามเดิมของคุณโดยนัย) หากเป็นรายการชุดจริง ๆ แล้วไม่มีองค์ประกอบแรกเพราะชุดไม่มีคำสั่ง
ที่นี่ฉันได้สร้างรายการแบนเพราะโดยทั่วไปดูเหมือนว่ามีประโยชน์มากกว่าการสร้างรายการ 1 องค์ประกอบ tuples แต่คุณสามารถสร้างรายชื่อของ 1 tuples องค์ประกอบโดยเพียงแค่การแทนที่ด้วยseq[0]
(seq[0],)
int() argument must be a string or a number, not 'QuerySet'
int()
ไม่มีวิธีแก้ไขปัญหาของฉันดังนั้นข้อยกเว้นที่คุณเห็นจะต้องปรากฏในภายหลังในรหัส
__in
เพื่อกรองข้อมูล
__in
อะไร - จากตัวอย่างอินพุตที่คุณให้มาสิ่งนี้จะสร้างรายการจำนวนเต็ม อย่างไรก็ตามหากรายการสิ่งอันดับของคุณไม่ได้เริ่มต้นด้วยจำนวนเต็มคุณจะไม่ได้รับจำนวนเต็มและคุณจะต้องทำให้เป็นจำนวนเต็มผ่านint
หรือพยายามหาสาเหตุที่องค์ประกอบแรกของคุณไม่สามารถแปลงเป็นจำนวนเต็มได้
new_list = [ seq[0] for seq in yourlist if type(seq[0]) == int]
ทำงานหรือไม่
คุณสามารถใช้ "tuple unpacking":
>>> my_list = [(1, u'abc'), (2, u'def')]
>>> my_ids = [idx for idx, val in my_list]
>>> my_ids
[1, 2]
ที่ย้ำเวลาในแต่ละ tuple เป็นจำนวนมาก ๆ และค่านิยมที่ได้รับการตั้งค่าให้ตัวแปรและidx
val
>>> x = (1, u'abc')
>>> idx, val = x
>>> idx
1
>>> val
u'abc'
นี่คือสิ่งที่operator.itemgetter
มีไว้เพื่อ
>>> a = [(1, u'abc'), (2, u'def')]
>>> import operator
>>> b = map(operator.itemgetter(0), a)
>>> b
[1, 2]
itemgetter
คำสั่งส่งกลับฟังก์ชั่นที่ส่งกลับดัชนีขององค์ประกอบที่คุณระบุ มันเหมือนกับการเขียน
>>> b = map(lambda x: x[0], a)
แต่ผมพบว่าitemgetter
เป็นที่ชัดเจนและที่ชัดเจนมากขึ้น
สิ่งนี้มีประโยชน์สำหรับการสร้างข้อความค้นหาแบบย่อ ตัวอย่างเช่น,
>>> c = sorted(a, key=operator.itemgetter(0), reverse=True)
>>> c
[(2, u'def'), (1, u'abc')]
จากมุมมองประสิทธิภาพใน python3.X
[i[0] for i in a]
และlist(zip(*a))[0]
เทียบเท่าlist(map(operator.itemgetter(0), a))
รหัส
import timeit
iterations = 100000
init_time = timeit.timeit('''a = [(i, u'abc') for i in range(1000)]''', number=iterations)/iterations
print(timeit.timeit('''a = [(i, u'abc') for i in range(1000)]\nb = [i[0] for i in a]''', number=iterations)/iterations - init_time)
print(timeit.timeit('''a = [(i, u'abc') for i in range(1000)]\nb = list(zip(*a))[0]''', number=iterations)/iterations - init_time)
เอาท์พุต
3.491014136001468e-05
3.422205176000717e-05
ถ้าสิ่งอันดับเป็นเอกลักษณ์สิ่งนี้สามารถใช้งานได้
>>> a = [(1, u'abc'), (2, u'def')]
>>> a
[(1, u'abc'), (2, u'def')]
>>> dict(a).keys()
[1, 2]
>>> dict(a).values()
[u'abc', u'def']
>>>
ordereddict
แม้ว่า
เมื่อฉันวิ่ง (ตามที่แนะนำข้างต้น):
>>> a = [(1, u'abc'), (2, u'def')]
>>> import operator
>>> b = map(operator.itemgetter(0), a)
>>> b
แทนที่จะกลับมา:
[1, 2]
ฉันได้รับสิ่งนี้เป็นผลตอบแทน:
<map at 0xb387eb8>
ฉันพบว่าฉันต้องใช้ list ():
>>> b = list(map(operator.itemgetter(0), a))
เพื่อส่งคืนรายการสำเร็จโดยใช้คำแนะนำนี้ ที่กล่าวว่าฉันมีความสุขกับการแก้ปัญหานี้ขอบคุณ (ทดสอบ / รันโดยใช้ Spyder, คอนโซล iPython, Python v3.6)
ฉันคิดว่ามันอาจจะมีประโยชน์ในการเปรียบเทียบ runtimes ของวิธีการที่แตกต่างกันดังนั้นฉันทำมาตรฐาน (ใช้ห้องสมุดsimple_benchmark )
I) เกณฑ์มาตรฐานมีสิ่งอันดับ 2 องค์ประกอบ
ตามที่คุณคาดหวังว่าจะเลือกองค์ประกอบแรกจากสิ่งอันดับโดยดัชนี0
แสดงให้เห็นว่าเป็นทางออกที่เร็วที่สุดใกล้กับวิธีการแก้ปัญหาการบรรจุโดยคาดหวังว่าค่า 2 ค่า
import operator
import random
from simple_benchmark import BenchmarkBuilder
b = BenchmarkBuilder()
@b.add_function()
def rakesh_by_index(l):
return [i[0] for i in l]
@b.add_function()
def wayneSan_zip(l):
return list(list(zip(*l))[0])
@b.add_function()
def bcattle_itemgetter(l):
return list(map(operator.itemgetter(0), l))
@b.add_function()
def ssoler_upacking(l):
return [idx for idx, val in l]
@b.add_function()
def kederrack_unpacking(l):
return [f for f, *_ in l]
@b.add_arguments('Number of tuples')
def argument_provider():
for exp in range(2, 21):
size = 2**exp
yield size, [(random.choice(range(100)), random.choice(range(100))) for _ in range(size)]
r = b.run()
r.plot()
II) เกณฑ์มาตรฐานที่มีสิ่งอันดับ 2 หรือมากกว่าองค์ประกอบ
import operator
import random
from simple_benchmark import BenchmarkBuilder
b = BenchmarkBuilder()
@b.add_function()
def kederrack_unpacking(l):
return [f for f, *_ in l]
@b.add_function()
def rakesh_by_index(l):
return [i[0] for i in l]
@b.add_function()
def wayneSan_zip(l):
return list(list(zip(*l))[0])
@b.add_function()
def bcattle_itemgetter(l):
return list(map(operator.itemgetter(0), l))
@b.add_arguments('Number of tuples')
def argument_provider():
for exp in range(2, 21):
size = 2**exp
yield size, [tuple(random.choice(range(100)) for _
in range(random.choice(range(2, 100)))) for _ in range(size)]
from pylab import rcParams
rcParams['figure.figsize'] = 12, 7
r = b.run()
r.plot()
สิ่งเหล่านั้นเป็นสิ่งอันดับไม่ใช่ชุด คุณสามารถทำได้:
l1 = [(1, u'abc'), (2, u'def')]
l2 = [(tup[0],) for tup in l1]
l2
>>> [(1,), (2,)]
คุณสามารถแกะ tuples ของคุณและรับเฉพาะองค์ประกอบแรกโดยใช้ list comprehension:
l = [(1, u'abc'), (2, u'def')]
[f for f, *_ in l]
เอาท์พุท:
[1, 2]
สิ่งนี้จะได้ผลไม่ว่าคุณจะมีองค์ประกอบกี่ตัวในสิ่งอันดับ:
l = [(1, u'abc'), (2, u'def', 2, 4, 5, 6, 7)]
[f for f, *_ in l]
เอาท์พุท:
[1, 2]
ฉันสงสัยว่าทำไมไม่มีใครแนะนำให้ใช้ numpy แต่ตอนนี้หลังจากตรวจสอบฉันเข้าใจ มันอาจจะไม่ดีที่สุดสำหรับอาร์เรย์ประเภทผสม
นี่จะเป็นวิธีแก้ปัญหาใน numpy:
>>> import numpy as np
>>> a = np.asarray([(1, u'abc'), (2, u'def')])
>>> a[:, 0].astype(int).tolist()
[1, 2]