2017-05-21 26 views
-1

我有一個如下所示的列表。 [0,0,0,0,0'entrya',5,'entryb',10,'anotherentry',7,'entry',1,'entryd',30,...,0,0, 0,0,0,0]在Python中對兩種不同類型的列表進行排序

等等,我覺得這個想法很清楚。我現在的問題是,我想在與字符串關聯的數字之後對整個列表進行排序。所以結果看起來像這樣。 ['entry',1,'entrya',5,'anotherentry',7,'entryb',10,'entryd',30,... 0,0,0,0](或者其他方式甚至會更好。)

我的問題很明顯是,相鄰的條目必須保持在一起,字典不允許用於此練習。

有沒有人有關於如何做到這一點的想法?

非常感謝!

+0

從列表中創建的元組,那麼元組進行排序,然後壓平列表。但是在開始和結束時沒有關聯,只有0.0 ... –

+0

爲什麼''entrya',5'從結果中錯過了? – RomanPerekhrest

+0

oops忘記了入口a。編輯 – Plinzelplein

回答

0

我不太確定,如果我瞭解您的原始列表是如何構建的。如果我們稱之爲x,並且每個偶數條目(0,2,...)都是一個字符串,並且每個奇數條目(1,3,...)都是與前面的字符串關聯的數字,則可以將其轉換爲元組如下:

y = zip(x[0::2], x[1::2]) 

元組的列表Y可以再進行排序:

y.sort(key=lambda t: t[1]) 

這將產生:

[(0, 0), 
(0, 0), 
(0, 0), 
(0, 0), 
(0, 0), 
(0, 0), 
('entry', 1), 
('entrya', 5), 
('anotherentry', 7), 
('entryb', 10), 
('entryd', 30)] 

這是否幫助?

編輯:

要再次將其壓平成一個列表:

z = [entry for tup in y for entry in tup] 
+0

開頭有零個奇數,所以這是行不通的。 – AChampion

+0

@AChampion我在想一個人可能會失蹤。如果該列表實際上是一個列表對,那麼它具有一個合理的結構。如果它只是任意數量的零並不真正攜帶任何信息,那麼我建議首先找到另一個數據表示。 – sigvaldm

+1

不,它工作得很好,奇數零是我的錯,對不起。它應該是零的偶數 – Plinzelplein

0

我的方法是在列表中首先壓縮的元素插入的元組是這樣的:後來

[('null', 0), ('null', 0), ('null', 0), ('entrya', 5), ('entryb', 10), ('anotherentry', 7), ...] 

,你可以通過第二個元素對元素進行排序。

ls = [0, 0, 0, 0, 0, 'entrya', 5, 'entryb', 10, 'anotherentry', 7, 
    'entry', 1, 'entryd', 30, 0, 0, 0, 0, 0, 0] 

ls_zip_elem = [] 
for x1, x2 in zip(ls, ls[1:]): 
    if x1 == 0: 
     ls_zip_elem.append(('null', x1)) 
    elif not str(x1).isdigit(): 
     ls_zip_elem.append((x1, x2)) 
    else: 
     pass 
ls_zip_elem_sorted = sorted(ls_zip_elem, key=lambda x: x[1]) # sorted 

# put the list back 
ls_sorted = [] 
for x1, x2 in ls_zip_elem_sorted: 
    if x1 == 'null': 
     ls_sorted.append(x2) 
    else: 
     ls_sorted.extend([x1, x2]) 

# output 
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'entry', 1, 'entrya', 5, 'anotherentry', 7, 
# 'entryb', 10, 'entryd', 30] 
0

這似乎是一個很奇怪的數據集,但假設你真的需要這則:
如果你在一開始移除0 S和末尾,則是相當容易進行排序:

>>> l = ['entrya', 5, 'entryb', 10, 'anotherentry', 7, 'entry', 1, 'entryd', 30] 
>>> [b for a in sorted(zip(*[iter(l)]*2), key=lambda x: x[1]) for b in a] 
['entry', 1, 'entrya', 5, 'anotherentry', 7, 'entryb', 10, 'entryd', 30 

因此,假設您沒有0作爲您的其他entries的值,那麼您可以將其作爲2種情況處理,將所有零對進行排序,然後將所有零加回去。

>>> l = [0,0,0,0,0,'entrya',5, 'entryb', 10, 'anotherentry', 7, 'entry', 1, 'entryd', 30, 0,0,0,0,0] 
>>> pairs = [b for a in sorted(zip(*[iter(filter(lambda x: x!=0, l))]*2), key=lambda x: x[1]) for b in a] 
>>> zeros = list(filter(lambda x: x == 0, l)) 
>>> pairs + zeros 
['entry', 1, 'entrya', 5, 'anotherentry', 7, 'entryb', 10, 'entryd', 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] 
0

您可以使用reducefunctools模塊,addoperatorzipsorted()有你所需的輸出。

NB:

在這個解決方案:

  • 你需要分析你的輸入列表並從中單獨的零。
  • 然後,創建從該數據的對,而無需在其零,基於在第二元件上
  • 最後級聯步驟2用步驟1的零的列表

這是一個例子:

from operator import add 
from functools import reduce 

data = [0,0,0,0,0,'entrya',5, 'entryb', 10, 'anotherentry', 7, 'entry', 1, 'entryd', 30, 0,0,0,0,0,0] 
non_zeros, zeros = [k for k in data if k is not 0], [0]*data.count(0) 
pairs = [[k,v] for k,v in zip(non_zeros[::2], non_zeros[1::2])] 

final = reduce(add, sorted(pairs, key= lambda x: x[1])) + zeros 
print(final) 

輸出:

['entry', 1, 'entrya', 5, 'anotherentry', 7, 'entryb', 10, 'entryd', 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]