1

次の 2 つのリストがあります。

ISO3166_CountryCodes_NO = [["NO","Norge"],["SE","Sverige"],["GR","Hellas"]]
ISO3166_CountryCodes_EN = [["NO","Norway"],["SE","Sweden"],["GR","Greece"]]

ご覧のとおり、国コードは常に同じですが、国名は異なります (翻訳が異なります)。次のような 1 つのリストを作成するにはどうすればよいですか。

ISO3166_CountryCodes = [["NO","Norge","Norway"],["SE","Sverige","Sweden"],["GR","Hellas","Greece"]]

最初のリストで for ループを使用してそれを行うことができ、各要素について 2 番目のリストを検索して、一般的な国コードを見つけることができます。次に、新しいリストに翻訳を追加しますが、この方法はやや不器用だと思います。

Pythonでこれを達成するためのより良い方法はありますか? たとえば、私がよく知っている Perl では、ハッシュ テーブルを使用します。

4

4 に答える 4

4

Python では、辞書はハッシュ テーブルです。まず、2 つの辞書を作成します。

NO_dict = {x[0]: x[1] for x in ISO3166_CountryCodes_NO}
EN_dict = {x[0]: x[1] for x in ISO3166_CountryCodes_EN}

これにより、次のことが得られます。

{'GR': 'Hellas', 'NO': 'Norge', 'SE': 'Sverige'}
{'GR': 'Greece', 'NO': 'Norway', 'SE': 'Sweden'}

次に、次のようにリストを作成できます。

final_list = [[k, NO_dict[k], EN_dict[k]] for k in NO_dict]

あなたに与える:

[['GR', 'Hellas', 'Greece'],
 ['SE', 'Sverige', 'Sweden'],
 ['NO', 'Norge', 'Norway']]

タプルに保存された名前を使用して、データを辞書に保持する方が後で簡単になる場合があります。次に例を示します。

final_dict = {k:(NO_dict[k], EN_dict[k]) for k in NO_dict}

略語をキーとして使用してアイテムを取得できるように、たとえば次のようにfinal_dict['NO']なります('Norge', 'Norway')

編集:OrderedDict

Python >= 2.7 を使用していて、順序が気になる場合でも、 を使用して辞書を使用できますOrderedDict。次に例を示します。

from collections import OrderedDict

# A list of lists can be used as input for an OrderedDict, so don't need to loop
NO_dict = OrderedDict(ISO3166_CountryCodes_NO)
EN_dict = OrderedDict(ISO3166_CountryCodes_EN)

# Assumes you want the result in the same order as the Norwegian list
# Iterate over the English list if it has a preferred order

final_dict = OrderedDict([(k, (NO_dict[k], EN_dict[k])) for k in NO_dict])

(別の実装については、AshwiniChaudhary の回答を参照してください)

于 2012-11-17T21:58:28.880 に答える
2

このようなもの、unique_everseenitertoolsのレシピとを使用chain():

In [26]: from itertools import *

In [27]: lis1=[["NO","Norge"],["SE","Sverige"],["GR","Hellas"]]

In [28]: lis2=[["NO","Norway"],["SE","Sweden"],["GR","Greece"]]

In [29]: from itertools import *

In [30]: def unique_everseen(iterable, key=None):
        seen = set()
        seen_add = seen.add
        if key is None:
                for element in ifilterfalse(seen.__contains__, iterable):
                        seen_add(element)
                        yield element
                else:
                        for element in iterable:
                                k = key(element)
                                if k not in seen:
                                        seen_add(k)
                                        yield element
   ....:                         

In [31]: [list(unique_everseen(chain(*x))) for x in izip(lis1,lis2)]
Out[31]: 
[['NO', 'Norge', 'Norway'],
 ['SE', 'Sverige', 'Sweden'],
 ['GR', 'Hellas', 'Greece']]

または:groupby itertools と組み合わせて使用​​できますoperator.itemgetter():

In [42]: from operator import *

In [43]: [[k]+list(map(itemgetter(1),g)) for x in zip(lis1,lis2) for k,g in groupby(x,itemgetter(0))]
Out[43]: 
[['NO', 'Norge', 'Norway'],
 ['SE', 'Sverige', 'Sweden'],
 ['GR', 'Hellas', 'Greece']]

またはcollections.OrderedDict、のサブクラスでdictあり、順序も維持する を使用します。

In [47]: from collections import OrderedDict

In [48]: dic=OrderedDict()

In [49]: for x in lis1:
   ....:     dic.setdefault(x[0],[]).append(x[1])
   ....:     

In [50]: for x in lis2:
    dic.setdefault(x[0],[]).append(x[1])
   ....:     

In [51]: dic
Out[51]: OrderedDict([('NO', ['Norge', 'Norway']), ('SE', ['Sverige', 'Sweden']), ('GR', ['Hellas', 'Greece'])])

In [52]: [[x]+y for x,y in dic.items()]
Out[52]: 
[['NO', 'Norge', 'Norway'],
 ['SE', 'Sverige', 'Sweden'],
 ['GR', 'Hellas', 'Greece']]

#or directly access the names using the short-name
In [53]: dic['NO']
Out[53]: ['Norge', 'Norway']

In [54]: dic['GR']
Out[54]: ['Hellas', 'Greece']
于 2012-11-17T21:50:00.690 に答える
1

リスト内包表記を使用できます:

>>> [[s]+
     [n for (c,n) in ISO3166_CountryCodes_NO if c==s]+
     [n for (c,n) in ISO3166_CountryCodes_EN if c==s]
     for s in set([c for (c,n) in ISO3166_CountryCodes_NO] + 
                  [c for (c,n) in ISO3166_CountryCodes_EN])]

[['GR', 'Hellas', 'Greece'], ['SE', 'Sverige', 'Sweden'], ['NO', 'Norge', 'Norway']]
于 2012-11-17T21:53:42.897 に答える
1

Python 3.2 を使用しています。

最初の方法:

[[i[0],i[1],v[1]] for i in list1 for v in list2  if i[0]==v[0]]

2 番目の方法:

res=[]
for i,v in list(zip(list1,list2):
    tem=[i[0]]
    if i[0]==v[0]: tem.extend([i[1],v[1]])
res.append(tem)
于 2012-11-18T15:39:55.387 に答える