0

pkg名が構造体で埋められた別のリスト内にすでにあるかどうかを確認する方法:

:test_pkg_list []には、次のようなものが含まれます。

test_pkg_list[0]: 

name = git
version = 1.0
description = git package

test_pkg_list[1]:

name = opengl
version = 1.25
description = graphics

So on...

したがって、私の目標は、名前の重複がないかリストを確認することでした。

def _pkg_exists_in_list(self, list, pkg_name):
        if len(list) >= 1:
            if any(pkg_name in item for item in list):
                return True 
            else:
                return False
        else:
            return False

2つのパラメーターを渡します。

test_pkg_list = [] #Note that this list does populate over time, at first its empty.
pkg_name = 'git'

#Call the method an pass the paramters
if self._pkg_exists_in_list(test_pkg_list, pkg_name) is False:
  #No duplicates found continue
else:
  #We found duplicate, stop.

次の例外エラーが引き続き発生します。

argument of type 'instance' is not iterable
4

2 に答える 2

4

あなたのコードは必要以上に複雑です。

def _pkg_exists_in_list(self, the_list, pkg_name):
    return pkg_name in the_list

理由は次のとおりです。

def _pkg_exists_in_list(self, list, pkg_name):  # don't call it list; don't overwrite built-ins
        if len(list) >= 1:   # Unnecessary; [] resolves Boolean to False
            if any(pkg_name in item for item in list): # can just check if an item is in a list using the `in` statement; no need to match every string to every string
                return True # Can just return the evaluation of an expression; poor form to explicitly return True/False after if statement
            else:
                return False
    else:
        return False

アップデート:

item in mylistコメントで述べたように、あなたのコードと同一ではany(mystring in item for item in mylist)なく、より詳細に言えば同等であると指摘する必要があると思いますany(mystring == item for item in mylist)。ただし、実際には==、部分文字列とin.

2 回目の更新:

辞書を使用するというAlexのアイデアは気に入っていますが、必須ではないかもしれません。

import re
def _pkg_exists_in_list(self, the_list, pkg_name):
    return any(re.search(r'name = ' + pkg_name, item) for item in the_list)

どちらがより効率的かという問題だと思います。

アップデート 2.1:

私の勝ち。

C:\Users\JJ>python -m timeit -s "p = ['''name = git\nversion = 1.0\nd
escription = git package''', '''name = opengl\nversion = 1.25\ndescription = gra
phics''']; import re" "dictlist = []" "for item in p:" " d = {}" " for line in i
tem.splitlines():" "  k, v = line.split('=')" "  d[k.strip()] = v.strip()" " dic
tlist.append(d)" "any('git' == x['name'] for x in dictlist)"
100000 loops, best of 3: 5.38 usec per loop

C:\Users\JJ>python -m timeit -s "p = ['''name = git\nversion = 1.0\nd
escription = git package''', '''name = opengl\nversion = 1.25\ndescription = gra
phics''']; import re" "any(re.search(r'name = ' + 'git', item) for item in p)"
1000000 loops, best of 3: 1.36 usec per loop
于 2013-01-06T07:35:18.967 に答える
3

文字列のリストを のリストに変換してから、dict次のようなものを使用して検索します。

test_pkg_list = [
"""name = git
version = 1.0
description = git package""",

"""name = opengl
version = 1.25
description = graphics"""]

dictlist = []

# Turn into a list of dictionaries
for item in test_pkg_list:
    d = {}
    for line in item.splitlines():
        k, v = line.split('=')
        d[k.strip()] = v.strip()
    dictlist.append(d)

print dictlist
# [
#    {'version': '1.0', 'name': 'git', 'description': 'git package'}, 
#    {'version': '1.25', 'name': 'opengl', 'description': 'graphics'}
# ]

searchname = 'git'

# Now search by name
print any(searchname == x['name'] for x in dictlist)

dict に変換する手間をかけたくない場合は、次のような簡単なことを行うことができます。

>>> searchname = 'git'
>>> print any(searchname in line for line in test_pkg_list)
True
>>> searchname = 'empty'
>>> print any(searchname in line for line in test_pkg_list)
False
>>> searchname = 'version' # This is a problem
>>> print any(searchname in line for line in test_pkg_list)
True

# Or to ensure it only matches the name:
>>> print any('name = ' + searchname in line for line in test_pkg_list)
False
>>> searchname = 'git'
>>> print any('name = ' + searchname in line for line in test_pkg_list)
True
>>> searchname = 'version'
>>> print any('name = ' + searchname in line for line in test_pkg_list)
False

または、名前だけを抽出することもできます。

for line in test_pkg_list:
    firstline = line.splitlines()[0]
    name = firstline.split('=')[1].strip()
    print name

1 行:

>>> names = [line.splitlines()[0].split('=')[1].strip() for line in test_pkg_list]
['git', 'opengl']

次に比較します。

>>> 'git' in names
True
>>> 'test' in names
False

パフォーマンスは次の使用に匹敵しreます: (速度の 65%)

>>> timeit.timeit("any(re.search(r'name = ' + 'git', item) for item in p)", "p = ['''name = git\nversion = 1.0\ndescription = git package''', '''name = opengl\nversion = 1.25\ndescription = graphics''']; import re")
2.338025673656987

>>> timeit.timeit("'git' in [line.splitlines()[0].split('=')[1].strip() for line in p]", "p = ['''name = git\nversion = 1.0\ndescription = git package''', '''name = opengl\nversion = 1.25\ndescription = graphics''']")
3.5689878827767245
于 2013-01-06T08:13:04.307 に答える