
[英]How to convert a list of lists with separate lists that have the same first element to a dictionary?
[英]Find how many lists in list have the same element
我是Python的新手,所以遇到了一些麻煩。 我在一個列表中有幾個字符串列表。
list=[ [['AA','A0'],['AB','A0']],
[['AA','B0'],['AB','A0']],
[['A0','00'],['00','A0'], [['00','BB'],['AB','A0'],['AA','A0']] ]
]
我必須找到多少個具有相同元素的列表。 例如,對於上面的列表,元素['AB','A0']
的正確結果是3,因為它是連接大部分元素的元素。
我寫了一些代碼...但是不好...它適用於列表中的兩個列表,但不適用於更多...。請幫助! 這是我的代碼...上面的清單...
for t in range(0,len(list)-1):
pattern=[]
flag=True
pattern.append(list[t])
count=1
rest=list[t+1:]
for p in pattern:
for j in p:
if flag==False:
break
pair= j
for i in rest:
for y in i:
if pair==y:
count=count+1
break
if brojac==len(list):
flag=False
break
由於您的數據結構相當復雜,因此您可能需要構建一個遞歸函數,該函數可以自我調用( http://en.wikipedia.org/wiki/Recursion_(computer_science) )。
此功能非常簡單。 您遍歷原始列表的所有項目。 如果當前項目等於要搜索的值,則將找到的對象數增加1。如果該項目本身是列表,則將遍歷該子列表並在該子列表中找到所有匹配項(通過在子列表而不是原始列表上調用相同的函數)。 然后,您可以通過子列表中的計數來增加找到的對象的總數。 我希望我的解釋是清楚的。
alist=[[['AA','A0'],['AB','A0']],[['AA','B0'],['AB','A0']],[['A0','00'],['00','A0'],[['00','BB'],['AB','A0'],['AA','A0']]]]
def count_in_list(val, arr):
val_is_list = isinstance(val, list)
ct = 0
for item in arr:
item_is_list = isinstance(item, list)
if item == val or (val_is_list and item_is_list and sorted(item) == sorted(val)):
ct += 1
if item_is_list :
ct += count_in_list(val, item)
return ct
print count_in_list(['AB', 'A0'], alist)
這是一種迭代方法,也可以使用python3來工作,該方法將獲取所有子列表的計數:
from collections import defaultdict
d = defaultdict(int)
def counter(lst, d):
it = iter(lst)
nxt = next(it)
while nxt:
if isinstance(nxt, list):
if nxt and isinstance(nxt[0], str):
d[tuple(nxt)] += 1
rev = tuple(reversed(nxt))
if rev in d:
d[rev] += 1
else:
lst += nxt
nxt = next(it,"")
return d
print((counter(lst, d)['AB', 'A0'])
3
它僅適用於像您的輸入這樣的數據,列表旁邊的字符串嵌套會破壞代碼。
要獲得單個子列表計數更容易:
def counter(lst, ele):
it = iter(lst)
nxt = next(it)
count = 0
while nxt:
if isinstance(nxt, list):
if ele in (nxt, nxt[::-1]):
count += 1
else:
lst += nxt
nxt = next(it, "")
return count
print(counter(lst, ['AB', 'A0']))
3
糟糕-這可能不是很好的代碼,但是這就是我要嘗試解決的方式。 請不要傷害我;-)
第一,
我將問題分成三個較小的部分:
1。
我仍然會使用嵌套列表,但是深度只有兩層。 要遍歷的外部列表及其內部的所有兩個值列表。 您可以在此處找到有關如何清除嵌套列表的大量信息。 因為我只是一個初學者,所以我無法從所有非常詳細的信息中受益匪淺-但如果向下滾動,您會發現一個與我相似的示例。 這就是我的理解,這就是我的能力。
請注意,這是一個遞歸函數。 正如您在評論中提到的那樣,您認為這不容易理解:我認為您是對的。 我將嘗試以某種方式進行解釋:
我不知道嵌套深度在您的列表中是否一致。 而且我不想自己提取值,因為您想使用列表。 因此,此函數遍歷外部列表。 對於每個元素,它都會檢查它是否是一個列表。 如果沒有,則什么也不會發生。 如果它是一個列表,則將查看該列表中的第一個元素。 它將再次檢查它是否為列表。
如果當前列表中的第一個元素是另一個列表,則將再次調用該函數-遞歸-但這一次從當前內部列表開始。 重復此操作,直到函數找到一個列表,該列表在第一個位置上包含一個不是列表的元素。
在您的示例中,它將遍歷完整的列表列表,直到找到您的第一個字符串值。 然后,它獲取包含該值的列表-並將其放在另一個列表中,然后返回該列表。
哦,男孩,這聽起來真是太瘋狂了-告訴我是否可以澄清任何事情... :-D
“喲,我想你喜歡清單,所以我把清單放在清單里……”
def get_inner_lists(some_list):
inner_lists = []
for item in some_list:
if hasattr(item, '__iter__') and not isinstance(item, basestring):
if hasattr(item[0], '__iter__') and not isinstance(item[0], basestring):
inner_lists.extend(get_inner_lists(item))
else:
inner_lists.append(item)
return inner_lists
無論如何-調用該函數,您會發現列表重新排列了一下:
>>> foo = [[['AA','A0'],['AB','A0']],[['AA','B0'],['AB','A0']],[['A0','00'],['00','A0'],[['00','BB'],['AB','A0'],['AA','A0']]]]
>>> print get_inner_lists(foo)
[['AA', 'A0'], ['AB', 'A0'], ['AA', 'B0'], ['AB', 'A0'], ['A0', '00'], ['00', 'A0'], ['00', 'BB'], ['AB', 'A0'], ['AA', 'A0']]
2。
現在,我將遍歷該列表並使用其值構建一個字符串。 這僅適用於兩個值的列表,但是正如您在示例中所顯示的那樣。 在迭代時,我將建立一個字典,將字符串作為鍵,將出現的值作為值。 這使得添加新值和增加現有值的計數器非常容易:
def count_list_values(some_list):
result = {}
for item in some_list:
str = item[0]+'-'+item[1]
if not str in result.keys():
result[str] = 1
else:
result[str] += 1
return result
在那里,所有計數都已完成。 我不知道是否需要它,但是副作用是所有值和所有情況都出現了:
>>> print count_list_values(get_inner_lists(foo))
{'00-A0': 1, '00-BB': 1, 'A0-00': 1, 'AB-A0': 3, 'AA-A0': 2, 'AA-B0': 1}
3。
但是您想要清晰的結果,因此讓我們循環瀏覽該字典,列出所有鍵和所有值,找到最大值-並返回相應的鍵。 用分隔符( -
)構建兩個值的字符串后,很容易將其拆分並再次列出該列表:
def get_max_dict_value(some_dict):
all_keys = []
all_values = []
for key, val in some_dict.items():
all_keys.append(key)
all_values.append(val)
return all_keys[all_values.index(max(all_values))].split('-')
如果定義了這三個小功能,然后將它們組合使用,那么您將獲得:
>>> print get_max_dict_value(count_list_values(get_inner_lists(foo)))
['AB', 'A0']
塔達! :-)
如果您確實有這樣的列表,其中僅包含9個元素,並且您不需要經常計算值-則手動進行。 通過讀取值並用手指計數。 這樣會容易得多;-)
否則,你去!
要么...
...您等到某個Guru出現並給您一個我從未見過的超快速,優雅的單行python命令時,它將執行相同的操作;-)
這很簡單,我可以合理地做到:
from collections import Counter
lst = [ [['AA','A0'],['AB','A0']],
[['AA','B0'],['AB','A0']],
[['A0','00'],['00','A0'], [['00','BB'],['AB','A0'],['AA','A0']] ]
]
def is_leaf(element):
return (isinstance(element, list) and
len(element) == 2 and
isinstance(element[0], basestring)
and isinstance(element[1], basestring))
def traverse(iterable):
for element in iterable:
if is_leaf(element):
yield tuple(sorted(element))
else:
for value in traverse(element):
yield value
value, count = Counter(traverse(lst)).most_common(1)[0]
print 'Value {!r} is present {} times'.format(value, count)
traverse()
生成產生一系列已排序的元組,它們表示列表中的每個項目。 Counter
對象對每個對象的出現次數進行計數,其.most_common(1)
方法返回最常見項目的值和計數。
您已經說過遞歸太困難了,但是我希望有所不同:這是解決此問題的最簡單方法。 您越早喜歡遞歸,就會越快樂。 :-)
希望這樣的東西就是您想要的。 這有點脆弱,建議遞歸更好。 但是由於您不希望這樣,所以這里有一些代碼可能會起作用。 我不太擅長python,但希望它能勝任:
def Compare(List):
#Assuming that the list input is a simple list like ["A1","B0"]
myList =[[['AA','A0'],['AB','A0']],[['AA','B0'],['AB','A0']],[['A0','00'],['00','A0'],[['00','BB'],['AB','A0'],['AA','A0']]]]
#Create a counter that will count if the elements are the same
myCounter = 0;
for innerList1 in myList:
for innerList2 in innerList1
for innerList3 in innerList2
for element in innerList3
for myListElements in myList
if (myListElements == element)
myCounter = myCounter + 1;
#I am putting the break here so that it counts how many lists have the
#same elements, not how many elements are the same in the lists
break;
return myCounter;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.