그런 식으로하고 싶습니다.
list_of_urls = ['http://www.google.fr/', 'http://www.google.fr/',
'http://www.google.cn/', 'http://www.google.com/',
'http://www.google.fr/', 'http://www.google.fr/',
'http://www.google.fr/', 'http://www.google.com/',
'http://www.google.fr/', 'http://www.google.com/',
'http://www.google.cn/']
urls = [{'url': 'http://www.google.fr/', 'nbr': 1}]
for url in list_of_urls:
if url in [f['url'] for f in urls]:
urls[??]['nbr'] += 1
else:
urls.append({'url': url, 'nbr': 1})
어떻게해야합니까? 튜플을 편집하거나 튜플 인덱스를 알아 내기 위해 튜플을 가져와야하는지 모르겠습니다.
도움이 필요하세요?
답변
그것은 사물을 정리하는 매우 이상한 방법입니다. 사전에 저장했다면 간단합니다.
# This example should work in any version of Python.
# urls_d will contain URL keys, with counts as values, like: {'http://www.google.fr/' : 1 }
urls_d = {}
for url in list_of_urls:
if not url in urls_d:
urls_d[url] = 1
else:
urls_d[url] += 1
카운트 사전을 업데이트하는이 코드는 Python에서 일반적인 “패턴”입니다. defaultdict이 작업을 더 쉽게하기 위해 만들어진 특수 데이터 구조 인은 매우 일반적입니다 .
from collections import defaultdict # available in Python 2.5 and newer
urls_d = defaultdict(int)
for url in list_of_urls:
urls_d[url] += 1
defaultdict키를 사용하여에 액세스하고 키가에 아직없는 defaultdict경우 키가 기본값으로 자동 추가됩니다. 는 defaultdict당신이 전달 된 호출 소요되며, 기본 값을 얻을를 호출합니다. 이 경우 우리는 클래스를 통과했습니다 int. 파이썬이 호출 int()하면 0 값을 반환합니다. 따라서 URL을 처음 참조하면 개수가 0으로 초기화 된 다음 개수에 1을 추가합니다.
그러나 카운트로 가득 찬 딕셔너리도 일반적인 패턴이므로 Python은 즉시 사용할 containers.Counter 수 Counter있는 클래스를 제공합니다. 클래스를 호출하여 인스턴스를 만들고 iterable을 전달하면됩니다. 키가 이터 러블의 값이고 값이 키가 이터 러블에 나타난 횟수를 계산하는 사전을 빌드합니다. 위의 예는 다음과 같습니다.
from collections import Counter # available in Python 2.7 and newer
urls_d = Counter(list_of_urls)
실제로 보여준 방식으로해야하는 경우 가장 쉽고 빠른 방법은이 세 가지 예제 중 하나를 사용한 다음 필요한 것을 구축하는 것입니다.
from collections import defaultdict # available in Python 2.5 and newer
urls_d = defaultdict(int)
for url in list_of_urls:
urls_d[url] += 1
urls = [{"url": key, "nbr": value} for key, value in urls_d.items()]
Python 2.7 이상을 사용하는 경우 한 줄로 수행 할 수 있습니다.
from collections import Counter
urls = [{"url": key, "nbr": value} for key, value in Counter(list_of_urls).items()]
답변
기본값을 사용하면 작동하지만 다음과 같이 작동합니다.
urls[url] = urls.get(url, 0) + 1
를 사용 .get하면 존재하지 않는 경우 기본 반환을 얻을 수 있습니다. 기본적으로 없음이지만 내가 보낸 경우에는 0이됩니다.
답변
defaultdict 사용 :
from collections import defaultdict
urls = defaultdict(int)
for url in list_of_urls:
urls[url] += 1
답변
이것은 항상 나를 위해 잘 작동합니다.
for url in list_of_urls:
urls.setdefault(url, 0)
urls[url] += 1
답변
정확히 당신의 방식대로하기 위해서? for … else 구조를 사용할 수 있습니다.
for url in list_of_urls:
for url_dict in urls:
if url_dict['url'] == url:
url_dict['nbr'] += 1
break
else:
urls.append(dict(url=url, nbr=1))
그러나 그것은 매우 우아하지 않습니다. 방문한 URL을 목록으로 저장해야합니까? 예를 들어 URL 문자열로 색인이 지정된 dict로 정렬하면 훨씬 더 깔끔합니다.
urls = {'http://www.google.fr/': dict(url='http://www.google.fr/', nbr=1)}
for url in list_of_urls:
if url in urls:
urls[url]['nbr'] += 1
else:
urls[url] = dict(url=url, nbr=1)
두 번째 예에서 유의해야 할 몇 가지 사항 :
- dict for를 사용하면 하나의 단일을 테스트 할 때
urls전체urls목록 을 살펴볼 필요가 없습니다url. 이 접근 방식은 더 빠를 것입니다. dict( )중괄호 대신 사용하면 코드가 짧아집니다.- 사용
list_of_urls,urls및url변수 이름은 구문 분석 코드가 매우 어렵게한다. 이 같은 명확한 무언가를 찾기 위해 더 나은urls_to_visit,urls_already_visited그리고current_url. 알아요, 더 길어요. 그러나 더 명확합니다.
그리고 물론 나는 그것이 dict(url='http://www.google.fr', nbr=1)당신 자신의 데이터 구조의 단순화 라고 가정하고 urls있습니다. 그렇지 않으면 단순히 다음과 같을 수 있기 때문입니다 .
urls = {'http://www.google.fr':1}
for url in list_of_urls:
if url in urls:
urls[url] += 1
else:
urls[url] = 1
defaultdict 자세로 매우 우아해질 수 있습니다 .
urls = collections.defaultdict(int)
for url in list_of_urls:
urls[url] += 1
답변
처음을 제외하고는 단어를 볼 때마다 if 문의 테스트가 실패합니다. 많은 수의 단어를 세는 경우 많은 단어가 여러 번 나올 것입니다. 값의 초기화가 한 번만 발생하고 해당 값의 증가가 여러 번 발생하는 상황에서 try 문을 사용하는 것이 더 저렴합니다.
urls_d = {}
for url in list_of_urls:
try:
urls_d[url] += 1
except KeyError:
urls_d[url] = 1
이에 대한 자세한 내용은 https://wiki.python.org/moin/PythonSpeed/PerformanceTips를 읽을 수 있습니다.
답변
