2015-01-06 4 views
0

у меня есть список кортежей и список с соответствующими значениями:Сортировать список кортежей с ноны и одновременно сортировать список, связанный

unsorted = [(1,3), (None,4), (19,31), (20,32), (8,None), (9,14)] 
dists = [3,None,4,5,None,9] 

Я хотел бы отсортировать «несортированный» список кортежей так выглядит что:

sorted = [(1,3), (None,4), (8,None), (9,14), (19,31), (20,32)] 

если один элемент кортежа не является ни один, возьмите второй (они всегда восходящие, так что никакая ситуация как [(8,12),(9,11)])

И в то же время я ш ульд любит сортировать связанную dists:

dists_sorted = [3, None, None, 9, 4, 5] 

Я знаю, что может это сделать так:

sorted, dists_sorted = (list(t) for t in zip(*sorted(zip(unsorted, dists)))) 

Но я понятия не имею, как правильно сортировать кортежи с ноной.

Заранее благодарен!

EDIT:

Я попробовал свои методы на более длинный список (он был уже отсортирован):

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)] 

Так начало разбился. У вас есть идеи, почему?

+0

Что вы подразумеваете под * началом разбитого *? –

+1

Не отсортировано: вы можете найти элементы в начале 'out' в оригинальном опубликованном списке. –

+0

Извините, я должен был быть более конкретным. Да, вместо (901,1) в начале я получил (Нет, 16). Есть ли для этого решение? – AirelleJab

ответ

2

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)] 

[EDIT] Основываясь на вышеизложенных замечаний, которые вы хотите правило, как этот (a,b) меньше (c,d), если и только:

  • если c и d не Nonec<d
  • если c или d не имеет a<b

... Но это не правило сортировки. В конце вашего примера вы говорите, что l отсортировано, но вы можете найти (916, None)<(None, 16)<(932, None): для этого нет правила.

1

вы можете использовать отсортированный с соответствующим 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)] 
+0

Я бы использовал 'is not None', потому что там могут быть нули. –

+0

@AshwiniChaudhary да его более эффективно, но я делаю это для этого случая! – Kasramvd

1

Один из способов (легче понять) будет:

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]) 

Оба приводят к тому же результату.

Edit:

Чтобы соответствовать тому, что вы сделали, вы можете сделать небольшое изменение функции 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.

Смежные вопросы