使用 Nones 对元组列表进行排序并同时对关联列表进行排序
Sort list of tuples with Nones and simultaneously sort associated list
我有一个元组列表和具有关联值的列表:
unsorted = [(1,3), (None,4), (19,31), (20,32), (8,None), (9,14)]
dists = [3,None,4,5,None,9]
我想对 'unsorted' 元组列表进行排序,使其看起来像这样:
sorted = [(1,3), (None,4), (8,None), (9,14), (19,31), (20,32)]
如果元组中有一个元素为None,则取第二个(它们总是升序的,所以不会出现[(8,12),(9,11)]
的情况)
同时我想对相关的 diss 进行排序:
dists_sorted = [3, None, None, 9, 4, 5]
我知道我可以这样做:
sorted, dists_sorted = (list(t) for t in zip(*sorted(zip(unsorted, dists))))
但是我不知道如何正确地对带有 Nones 的元组进行排序。
提前致谢!
编辑:
我在更长的列表上尝试了你的方法(它已经排序):
l = [(901, 1), (902, 2), (903, 3), (904, 4), (905, 5), (906, 6), (907, 7), (908, 8), (909, 9), (910, 10), (911, 11), (912, 12), (913, 13), (914, 14), (915, 15), (916, None), (None, 16), (None, 17), (917, 18), (918, 19), (None, 20), (919, 21), (920, 22), (921, 23), (922, 24), (923, 25), (924, 26), (925, 27), (926, 28), (927, 29), (928, 30), (929, 31), (930, 32), (931, 33), (932, None), (933, None), (934, None), (935, None), (None, 34), (None, 35), (None, 36), (None, 37), (None, 38), (None, 39), (936, 40), (937, None), (938, None), (939, 41), (940, 42), (941, 43), (942, 44), (943, 45), (944, 46), (945, 47), (946, 48), (947, 49), (948, 50), (949, 51), (950, 52), (951, 53), (952, 54), (953, 55), (954, 56), (955, 57), (956, 58), (957, 59), (958, 60), (959, 61), (960, 62), (961, 63), (962, 64), (963, 65), (964, 66), (965, 67), (966, 68), (967, 69), (968, 70), (969, 71), (970, 72), (971, 73), (972, 74), (973, None), (974, None), (975, None), (None, 75), (None, 76), (None, 77)]
我得到了这个:
out = [(None, 16), (None, 17), (None, 20), (None, 34), (None, 35), (None, 36), (None, 37), (None, 38), (None, 39), (None, 75), (None, 76), (None, 77), (901, 1), (902, 2), (903, 3), (904, 4), (905, 5), (906, 6), (907, 7), (908, 8), (909, 9), (910, 10), (911, 11), (912, 12), (913, 13), (914, 14), (915, 15), (916, None), (917, 18), (918, 19), (919, 21), (920, 22), (921, 23), (922, 24), (923, 25), (924, 26), (925, 27), (926, 28), (927, 29), (928, 30), (929, 31), (930, 32), (931, 33), (932, None), (933, None), (934, None), (935, None), (936, 40), (937, None), (938, None), (939, 41), (940, 42), (941, 43), (942, 44), (943, 45), (944, 46), (945, 47), (946, 48), (947, 49), (948, 50), (949, 51), (950, 52), (951, 53), (952, 54), (953, 55), (954, 56), (955, 57), (956, 58), (957, 59), (958, 60), (959, 61), (960, 62), (961, 63), (962, 64), (963, 65), (964, 66), (965, 67), (966, 68), (967, 69), (968, 70), (969, 71), (970, 72), (971, 73), (972, 74), (973, None), (974, None), (975, None)]
所以一开始就崩溃了。你知道为什么吗?
你可以使用 sorted 和适当的 key
:
>>> sorted(unsorted,key= lambda x: x[0] if x[0] else x[1])
[(1, 3), (None, 4), (8, None), (9, 14), (19, 31), (20, 32)]
如评论中所述,如果您可能有零,请使用 is not None
检查 None
:
>>> sorted(unsorted,key= lambda x: x[0] if x[0] is not None else x[1])
[(1, 3), (None, 4), (8, None), (9, 14), (19, 31), (20, 32)]
key
参数可以帮你解决。不管怎样,看看 sorted mini HOWTO。是很好的资源。
>>> unsorted = [(1,3), (None,4), (19,31), (20,32), (8,None), (9,14)]
>>> sorted(unsorted, key=lambda x:x[0] if x[0] is not None else x[1])
[(1, 3), (None, 4), (8, None), (9, 14), (19, 31), (20, 32)]
[编辑]
根据以上评论,您想要这样的规则 (a,b)
小于 (c,d)
当且仅当:
- 如果
c
和 d
不是 None
c<d
- 如果
c
或 d
是 None a<b
...但这不是排序规则。在示例的末尾,您说 l
已排序,但您可以找到 (916, None)<(None, 16)<(932, None)
:没有规则可以做到这一点。
一种方式(更容易理解)是:
def f(e):
if e[0] is None:
return e[1]
return e[0]
print sorted(unsorted, key = f)
使用 lambda
的简化方法是:
print sorted(unsorted, lambda e: e[1] if e[0] is None else e[0])
两者导致相同的结果。
编辑:
为了配合你所做的,你可以对函数做一点修改f
:
def f(e):
if e[0][0] is None:
return e[0][1]
return e[0][0]
sorted1, dists_sorted = (list(t) for t in zip(*sorted(zip(unsorted, dists), key = f)))
>>>
[(1, 3), (None, 4), (8, None), (9, 14), (19, 31), (20, 32)]
[3, None, None, 9, 4, 5]
注意e[0]
是unsorted
的项目,e[1]
是dists
中对应的项目。
我有一个元组列表和具有关联值的列表:
unsorted = [(1,3), (None,4), (19,31), (20,32), (8,None), (9,14)]
dists = [3,None,4,5,None,9]
我想对 'unsorted' 元组列表进行排序,使其看起来像这样:
sorted = [(1,3), (None,4), (8,None), (9,14), (19,31), (20,32)]
如果元组中有一个元素为None,则取第二个(它们总是升序的,所以不会出现[(8,12),(9,11)]
的情况)
同时我想对相关的 diss 进行排序:
dists_sorted = [3, None, None, 9, 4, 5]
我知道我可以这样做:
sorted, dists_sorted = (list(t) for t in zip(*sorted(zip(unsorted, dists))))
但是我不知道如何正确地对带有 Nones 的元组进行排序。
提前致谢!
编辑:
我在更长的列表上尝试了你的方法(它已经排序):
l = [(901, 1), (902, 2), (903, 3), (904, 4), (905, 5), (906, 6), (907, 7), (908, 8), (909, 9), (910, 10), (911, 11), (912, 12), (913, 13), (914, 14), (915, 15), (916, None), (None, 16), (None, 17), (917, 18), (918, 19), (None, 20), (919, 21), (920, 22), (921, 23), (922, 24), (923, 25), (924, 26), (925, 27), (926, 28), (927, 29), (928, 30), (929, 31), (930, 32), (931, 33), (932, None), (933, None), (934, None), (935, None), (None, 34), (None, 35), (None, 36), (None, 37), (None, 38), (None, 39), (936, 40), (937, None), (938, None), (939, 41), (940, 42), (941, 43), (942, 44), (943, 45), (944, 46), (945, 47), (946, 48), (947, 49), (948, 50), (949, 51), (950, 52), (951, 53), (952, 54), (953, 55), (954, 56), (955, 57), (956, 58), (957, 59), (958, 60), (959, 61), (960, 62), (961, 63), (962, 64), (963, 65), (964, 66), (965, 67), (966, 68), (967, 69), (968, 70), (969, 71), (970, 72), (971, 73), (972, 74), (973, None), (974, None), (975, None), (None, 75), (None, 76), (None, 77)]
我得到了这个:
out = [(None, 16), (None, 17), (None, 20), (None, 34), (None, 35), (None, 36), (None, 37), (None, 38), (None, 39), (None, 75), (None, 76), (None, 77), (901, 1), (902, 2), (903, 3), (904, 4), (905, 5), (906, 6), (907, 7), (908, 8), (909, 9), (910, 10), (911, 11), (912, 12), (913, 13), (914, 14), (915, 15), (916, None), (917, 18), (918, 19), (919, 21), (920, 22), (921, 23), (922, 24), (923, 25), (924, 26), (925, 27), (926, 28), (927, 29), (928, 30), (929, 31), (930, 32), (931, 33), (932, None), (933, None), (934, None), (935, None), (936, 40), (937, None), (938, None), (939, 41), (940, 42), (941, 43), (942, 44), (943, 45), (944, 46), (945, 47), (946, 48), (947, 49), (948, 50), (949, 51), (950, 52), (951, 53), (952, 54), (953, 55), (954, 56), (955, 57), (956, 58), (957, 59), (958, 60), (959, 61), (960, 62), (961, 63), (962, 64), (963, 65), (964, 66), (965, 67), (966, 68), (967, 69), (968, 70), (969, 71), (970, 72), (971, 73), (972, 74), (973, None), (974, None), (975, None)]
所以一开始就崩溃了。你知道为什么吗?
你可以使用 sorted 和适当的 key
:
>>> sorted(unsorted,key= lambda x: x[0] if x[0] else x[1])
[(1, 3), (None, 4), (8, None), (9, 14), (19, 31), (20, 32)]
如评论中所述,如果您可能有零,请使用 is not None
检查 None
:
>>> sorted(unsorted,key= lambda x: x[0] if x[0] is not None else x[1])
[(1, 3), (None, 4), (8, None), (9, 14), (19, 31), (20, 32)]
key
参数可以帮你解决。不管怎样,看看 sorted mini HOWTO。是很好的资源。
>>> unsorted = [(1,3), (None,4), (19,31), (20,32), (8,None), (9,14)]
>>> sorted(unsorted, key=lambda x:x[0] if x[0] is not None else x[1])
[(1, 3), (None, 4), (8, None), (9, 14), (19, 31), (20, 32)]
[编辑]
根据以上评论,您想要这样的规则 (a,b)
小于 (c,d)
当且仅当:
- 如果
c
和d
不是None
c<d
- 如果
c
或d
是 Nonea<b
...但这不是排序规则。在示例的末尾,您说 l
已排序,但您可以找到 (916, None)<(None, 16)<(932, None)
:没有规则可以做到这一点。
一种方式(更容易理解)是:
def f(e):
if e[0] is None:
return e[1]
return e[0]
print sorted(unsorted, key = f)
使用 lambda
的简化方法是:
print sorted(unsorted, lambda e: e[1] if e[0] is None else e[0])
两者导致相同的结果。
编辑:
为了配合你所做的,你可以对函数做一点修改f
:
def f(e):
if e[0][0] is None:
return e[0][1]
return e[0][0]
sorted1, dists_sorted = (list(t) for t in zip(*sorted(zip(unsorted, dists), key = f)))
>>>
[(1, 3), (None, 4), (8, None), (9, 14), (19, 31), (20, 32)]
[3, None, None, 9, 4, 5]
注意e[0]
是unsorted
的项目,e[1]
是dists
中对应的项目。