1

私は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
4

6 に答える 6

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]]
于 2013-01-11T00:23:20.577 に答える
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}

それをlistof に戻す方法は明らかなはずなlistので、それはあなたに任せます。

これにより順序が失われることに注意してください。ただし、 で簡単に修正できますOrderedDict。また、同一性も失いますlist。たとえば、[2, 2, 2, 2]最後に返される は と等しくなりますが、元の とは異なります[2, 2, 2, 2]。しかし、これも簡単に修正できます。sublistを使用する代わりに、 を直接保存するだけcountです。とにかく、これらのどちらもあなたの問題には関係ないと思います。

于 2013-01-11T00:23:37.267 に答える
1

簡単な解決策は、並べ替えられたリストをリストの最初の要素としてキーを持つ dict に変換することです。これにより、最終的にキーに基づいて重複が削除されます。

>>> {e[0]: e for e in sorted(l)}.values()
[[2, 2, 2, 2], [3, 3], [5], [7], [11], [13], [17], [19]]

dict 内包表記が利用できない Python バージョン < 2.7 の場合

>>> dict((e[0], e) for e in sorted(l)).values()
[[2, 2, 2, 2], [3, 3], [5], [7], [11], [13], [17], [19]]
于 2013-01-11T04:26:35.093 に答える
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ループを使用したリスト内包表記だけだと思いますが、うまく機能します。

于 2013-01-11T00:27:16.677 に答える
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]]
于 2013-01-11T00:36:49.267 に答える
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]]
于 2013-01-11T01:02:28.913 に答える