我是Python的新手,所以我遇到了麻烦。我在一个列表中有一些字符串列表。
list=[ [['AA','A0'],['AB','A0']],
[['AA','B0'],['AB','A0']],
[['A0','00'],['00','A0'], [['00','BB'],['AB','A0'],['AA','A0']] ]
]
我必须找到有多少列表具有相同的元素。例如,对于元素['AB','A0']
,上面列表的正确结果是3,因为它是连接大多数元素的元素。
我写了一些代码......但它并不好......它适用于列表中的2个列表,但不是更多.... 请帮忙! 这是我的代码......对于上面的列表...
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
答案 0 :(得分:2)
由于您的数据结构相当复杂,您可能希望构建一个递归函数,这是一个自我调用的函数(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)
答案 1 :(得分:1)
这是一种迭代方法,也可以使用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
答案 2 :(得分:0)
Ooookay - 这可能不是一个非常好的和简单的代码,但这就是我试图解决这个问题的方法。请不要伤害我; - )
<强>首先,强>
我将问题分成三个较小的问题:
<强> 1 强>
我仍然使用嵌套列表,但只使用两级深度。外部列表,迭代,以及其中的所有两个值列表。您可以获得有关如何摆脱嵌套列表 right here 的大量信息。由于我只是一个初学者,我无法从所有非常详细的信息中做出太多贡献 - 但如果向下滚动,你会发现一个类似于我的例子。这就是我的理解,这就是我能做的。
请注意,它是一个递归函数。正如你在评论中提到的,你认为这不容易理解:我认为你是对的。我会尝试以某种方式解释它:
我不知道您的列表中的嵌套深度是否一致。并且我不想将值本身提取出来,因为您希望使用列表。所以这个函数循环遍历外部列表。对于每个元素,它会检查它是否为列表。如果没有,没有任何反应。如果它是一个列表,它将查看该列表中的第一个元素。它会再次检查它是否是一个列表。
如果当前列表中的第一个元素是另一个列表,则将再次调用该函数 - 递归 - 但这次是从当前内部列表开始。重复此过程,直到函数找到一个列表,其中包含第一个位置上不是列表的元素。
在您的示例中,它将深入查看完整的列表列表,直到找到您的第一个字符串值。然后它获取包含该值的列表 - 并将其放入另一个列表中,即返回的列表。
哦,小伙子,听起来真的很疯狂 - 告诉我,如果澄清了什么...... :-D
“哟dawg,我喜欢你喜欢的列表,所以我把列表放在列表中......”
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']
的Ta-DAA! : - )
如果您确实只有9个元素的列表,并且您不需要经常计算值 - 手动执行。通过读取值并用手指计数。它会变得如此简单; - )
否则,你走吧!
或... 强>
...你等到一些Guru出现并给你一个我以前从未见过的超快速,优雅的单行蟒蛇命令,它会做同样的事情; - )
答案 3 :(得分:0)
这很简单,我可以合理地做到:
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()
generate会生成一系列排序元组,表示列表中的每个项目。 Counter
对象计算每个对象的出现次数,其.most_common(1)
方法返回最常见项的值和计数。
你说过递归太难了,但我不同意见:这是解决这个问题的最简单方法。你越早来爱递归,你就越快乐。 : - )
答案 4 :(得分:-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;