我在Python中有以下列表:
l = [[2], [3], [2, 2], [5], [2], [3], [7], [2, 2, 2], [3, 3], [2], [5], [11], [2, 2], [3], [13], [2], [7], [3], [5], [2, 2, 2, 2], [17], [2], [3, 3], [19], [2, 2], [5]]
我想写一个函数,它将返回最大长度的唯一值子列表。在这种情况下,函数将返回:
l = [[5], [7], [3, 3], [11], [13], [2, 2, 2, 2], [17], [19]]
我仍然是python的初学者,但我对如何编写这样的函数却知之甚少。我得到的最远的是弄清楚我可以通过使用嵌套循环迭代子列表。但是从我所看到的Python看来,似乎必须有一些更简单的方法来返回我正在寻找的列表而不是使用循环。
更新
以下是我对代码所做的事情:解决项目euler#5,非暴力方式!
我确信这段代码可以重构,但无论如何。
谢谢你的帮助,伙计们。 itemgetter
正是我所需要的。
#!/usr/bin/python
# coding = UTF-8
import argparse, sys, math
from itertools import groupby
from collections import defaultdict
from operator import itemgetter
parser = argparse.ArgumentParser()
parser.add_argument('filename', nargs='?')
args = parser.parse_args()
if args:
intinput = int(sys.argv[1])
elif not sys.stdin.isatty():
intinput = int(sys.stdin.read())
else:
parser.print_help()
def prime_factorize(n):
factors = []
number = math.fabs(n)
while number > 1:
factor = get_next_prime_factor(number)
factors.append(factor)
number /= factor
if n < -1:
factors[0] = -factors[0]
return factors
def get_next_prime_factor(n):
if n % 2 == 0:
return 2
for x in range(3, int(math.ceil(math.sqrt(n)) + 1), 2):
if n % x == 0:
return x
return int(n)
def mkfactors(n):
tpf = []
for i in range(n+1):
tpf.extend(prime_factorize(i))
return tpf
l = [list(g) for k,g in groupby(mkfactors(intinput))]
m = [max(g) for _,g in groupby(sorted(l,key=itemgetter(0)),key=itemgetter(0))]
prod = 1
for list in m:
for element in list:
prod *= element
print prod
答案 0 :(得分:2)
如果你知道每个子列表都有相同的元素,你可以这样做:
l = [[2], [3], [2, 2], [5], [2], [3], [7], [2, 2, 2], [3, 3], [2], [5], [11], [2, 2], [3], [13], [2], [7], [3], [5], [2, 2, 2, 2], [17], [2], [3, 3], [19], [2, 2], [5]]
from collections import defaultdict
my_dict = defaultdict(list)
for ele in l:
if len(my_dict[ele[0]]) < len(ele):
my_dict[ele[0]] = ele
结果:
>>> my_dict.values()
[[2, 2, 2, 2], [3, 3], [5], [7], [11], [13], [17], [19]]
答案 1 :(得分:2)
这里最简单的方法是使用一个使问题变得简单的数据结构,然后你可以随时转换回来。
例如,dict
映射键(素数)到长度(指数)很容易。所以:
>>> l = [[2], [3], [2, 2], [5], [2], [3], [7], [2, 2, 2], [3, 3], [2], [5], [11], [2, 2], [3], [13], [2], [7], [3], [5], [2, 2, 2, 2], [17], [2], [3, 3], [19], [2, 2], [5]]
>>> d = {}
>>> for sublist in l:
... value, count = sublist[0], len(sublist)
... if count > d.get(value, 0):
... d[value] = count
>>> d
{2: 4, 3: 2, 5: 1, 7: 1, 11: 1, 13: 1, 17: 1, 19: 1}
应该很明显如何将其转回list
list
,所以我会留给你。
请注意,这会丢失订单,但您可以通过OrderedDict
轻松解决此问题。它也会失去list
身份 - 例如,你在最后得到的[2, 2, 2, 2]
将等于,但不会与相同,原[2, 2, 2, 2]
。但这很容易修复 - 只是直接存储sublist
而不是使用count
。无论如何,我认为其中任何一个都与你的问题无关。
答案 2 :(得分:1)
l = [[2], [3], [2, 2], [5], [2], [3], [7], [2, 2, 2], [3, 3], [2], [5], [11], [2, 2], [3], [13], [2], [7], [3], [5], [2, 2, 2, 2], [17], [2], [3, 3], [19], [2, 2], [5]]
l = [max(i for i in l if j in i) for j in (2, 3, 5, 7, 11, 13, 17, 19)]
print(l)
# [[2, 2, 2, 2], [3, 3], [5], [7], [11], [13], [17], [19]]
我猜这只是一个嵌套for循环的列表理解,但它工作正常。
答案 3 :(得分:1)
使用collections.Counter
和sets
:
In [47]: s=set([x[0] for x in lis])
In [48]: c=[Counter(x) for x in lis]
In [49]: [max(c,key=lambda y:y[x]) for x in s]
Out[49]:
[Counter({2: 4}),
Counter({3: 2}),
Counter({5: 1}),
Counter({7: 1}),
Counter({11: 1}),
Counter({13: 1}),
Counter({17: 1}),
Counter({19: 1})]
另一种方式:
In [64]: from collections import defaultdict
In [65]: d=defaultdict(list)
In [66]: for x in lis:
d[x[0]].append(len(x))
....:
In [67]: [[x]*max(y) for x,y in d.items()]
Out[67]: [[2, 2, 2, 2], [3, 3], [5], [7], [11], [13], [17], [19]]
答案 4 :(得分:1)
from itertools import groupby
from operator import itemgetter
[max(g) for _,g in groupby(sorted(l),key=itemgetter(0))]
出:
[[2, 2, 2, 2], [3, 3], [5], [7], [11], [13], [17], [19]]
答案 5 :(得分:1)
一个简单的解决方案是将已排序的列表转换为dict,其中key作为列表的第一个元素,最终将根据键删除重复项。
>>> {e[0]: e for e in sorted(l)}.values()
[[2, 2, 2, 2], [3, 3], [5], [7], [11], [13], [17], [19]]
for Python Version&lt; 2.7无法获得字典理解
>>> dict((e[0], e) for e in sorted(l)).values()
[[2, 2, 2, 2], [3, 3], [5], [7], [11], [13], [17], [19]]