以排序顺序迭代一对迭代a
和b
的一种方法(最快的方法?)是链接它们并对链式迭代进行排序:
for i in sorted(chain(a, b)):
print i
例如,如果每个iterable的元素是:
a: 4, 6, 1
b: 8, 3
然后这个构造将按顺序生成元素
1, 3, 4, 6, 8
但是,如果迭代迭代对象,则按对象的内存地址对对象进行排序。假设每个iterable迭代相同类型的对象,
迭代特定内容的最快方法是什么? 对象的属性,按此属性排序?
如果要选择的属性在iterables之间有所不同怎么办?如果iterables a
和b
都迭代foo
类型的对象,它们具有相同类型的属性foo.x
和foo.y
,那么如何迭代元素按a
排序的x
和按b
排序的y
?
对于#2的示例,如果
a: (x=4,y=3), (x=6,y=2), (x=1,y=7)
b: (x=2,y=8), (x=2,y=3)
然后应按顺序生成元素
1, 3, 4, 6, 8
和以前一样。请注意,只有来自x
的{{1}}属性和来自a
的{{1}}属性才会输入排序和结果。
答案 0 :(得分:3)
在Python 2中:
>>> a = [1+4j, 7+0j, 3+6j, 9+2j, 5+8j]
>>> b = [2+5j, 8+1j, 4+7j, 0+3j, 6+9j]
>>> keyed_a = ((n.real, n) for n in a)
>>> keyed_b = ((n.imag, n) for n in b)
>>> from itertools import chain
>>> sorted_ab = zip(*sorted(chain(keyed_a, keyed_b), key=lambda t: t[0]))[1]
>>> sorted_ab
((1+4j), (8+1j), (3+6j), 3j, (5+8j), (2+5j), (7+0j), (4+7j), (9+2j), (6+9j))
因为在Python 3中zip()
返回一个迭代器,我们需要在尝试下标之前将其强制转换为列表:
>>> # ... as before up to 'from itertools import chain'
>>> sorted_ab = list(zip(*sorted(chain(keyed_a, keyed_b), key=lambda t: t[0])))[1]
>>> sorted_ab
((1+4j), (8+1j), (3+6j), 3j, (5+8j), (2+5j), (7+0j), (4+7j), (9+2j), (6+9j))
答案 1 :(得分:2)
回答问题1:您可以为sorted()
提供key
属性。例如,如果您想按对象的.name
排序,请使用
sorted(chain(a, b), key=lambda x: x.name)
关于问题2:我猜你需要foo.z
可以访问的每个对象的另一个属性(如sorted()
,如Zero Piraeus所建议的那样),因为该函数无法使用告诉它当前正在排序的对象来自何处。毕竟,它正在从chain()
接收一个新的迭代器,它不包含有关当前元素是来自a
还是b
的任何信息。