이 코드에서 list [:]의 의미는 무엇입니까?
이 질문에 이미 답변이 있습니다.
이 코드는 Python의 문서에서 가져온 것입니다. 조금 혼란 스러워요.
words = ['cat', 'window', 'defenestrate']
for w in words[:]:
if len(w) > 6:
words.insert(0, w)
print(words)
그리고 다음은 처음에 내가 생각한 것입니다.
words = ['cat', 'window', 'defenestrate']
for w in words:
if len(w) > 6:
words.insert(0, w)
print(words)
이 코드가 무한 루프를 생성하고 첫 번째 코드는 생성하지 않는 이유는 무엇입니까?
이것은 잡힌 것 중 하나입니다! 초보자를 피할 수있는 파이썬의.
는 words[:]
여기에 마법의 소스입니다.
관찰 :
>>> words = ['cat', 'window', 'defenestrate']
>>> words2 = words[:]
>>> words2.insert(0, 'hello')
>>> words2
['hello', 'cat', 'window', 'defenestrate']
>>> words
['cat', 'window', 'defenestrate']
그리고 이제 [:]
:
>>> words = ['cat', 'window', 'defenestrate']
>>> words2 = words
>>> words2.insert(0, 'hello')
>>> words2
['hello', 'cat', 'window', 'defenestrate']
>>> words
['hello', 'cat', 'window', 'defenestrate']
여기서 주목해야 할 중요한 것은 기존 목록의 words[:]
a 를 반환 copy
하므로 수정되지 않은 복사본을 반복한다는 것입니다.
다음을 사용하여 동일한 목록을 참조하고 있는지 확인할 수 있습니다 id()
.
첫 번째 경우 :
>>> words2 = words[:]
>>> id(words2)
4360026736
>>> id(words)
4360188992
>>> words2 is words
False
두 번째 경우 :
>>> id(words2)
4360188992
>>> id(words)
4360188992
>>> words2 is words
True
slicing operator[i:j]
라고 불리는 것은 주목할 가치가 있으며, 그것이하는 일은 index 에서 시작하여 index 까지 (하지만 포함하지 않는) 목록의 새로운 복사본을 반환한다는 것 입니다.i
j
그래서 words[0:2]
당신에게
>>> words[0:2]
['hello', 'cat']
시작 색인 0
을 생략하면 기본값이 로 설정되고 마지막 색인을 생략하면 기본값이 len(words)
로 설정되며 최종 결과는 전체 목록 의 사본을 받게 됩니다.
코드를 좀 더 읽기 쉽게 만들고 싶다면 copy
모듈을 추천합니다 .
from copy import copy
words = ['cat', 'window', 'defenestrate']
for w in copy(words):
if len(w) > 6:
words.insert(0, w)
print(words)
이것은 기본적으로 첫 번째 코드 스 니펫과 동일한 작업을 수행하며 훨씬 더 읽기 쉽습니다.
또는 (주석에서 DSM이 언급했듯이) python> = 3 words.copy()
에서 동일한 작업을 수행하는 것을 사용할 수도 있습니다 .
words[:]
copies all the elements in words
into a new list. So when you iterate over words[:]
, you're actually iterating over all the elements that words
currently has. So when you modify words
, the effects of those modifications are not visible in words[:]
(because you called on words[:]
before starting to modify words
)
In the latter example, you are iterating over words
, which means that any changes you make to words
is indeed visible to your iterator. As a result, when you insert into index 0 of words
, you "bump up" every other element in words
by one index. So when you move on to the next iteration of your for-loop, you'll get the element at the next index of words
, but that's just the element that you just saw (because you inserted an element at the beginning of the list, moving all the other element up by an index).
To see this in action, try the following code:
words = ['cat', 'window', 'defenestrate']
for w in words:
print("The list is:", words)
print("I am looking at this word:", w)
if len(w) > 6:
print("inserting", w)
words.insert(0, w)
print("the list now looks like this:", words)
print(words)
(In addition to @Coldspeed answer)
Look at the below examples:
words = ['cat', 'window', 'defenestrate']
words2 = words
words2 is words
results: True
It means names word
and words2
refer to the same object.
words = ['cat', 'window', 'defenestrate']
words2 = words[:]
words2 is words
results: False
In this case, we have created the new object.
Let's have a look at iterator and iterables:
An iterable is an object that has an
__iter__
method which returns an iterator, or which defines a__getitem__
method that can take sequential indexes starting from zero (and raises anIndexError
when the indexes are no longer valid). So an iterable is an object that you can get an iterator from.
An iterator is an object with a next
(Python 2) or __next__
(Python 3) method.
iter(iterable)
returns iterator object, and list_obj[:]
returns a new list object, exact copy of list_object.
In your first case:
for w in words[:]
The for
loop will iterate over new copy of the list not the original words. Any change in words has no effect on loop iteration, and the loop terminates normally.
This is how the loop does its work:
loop calls
iter
method on iterable and iterates over the iteratorloop calls
next
method on iterator object to get next item from iterator. This step is repeated until there are no more elements leftloop terminates when a
StopIteration
exception is raised.
In your second case:
words = ['cat', 'window', 'defenestrate']
for w in words:
if len(w) > 6:
words.insert(0, w)
print(words)
You are iterating over the original list words and adding elements to words have a direct impact on the iterator object. So every time your words is updated, the corresponding iterator object is also updated and therefore creates an infinite loop.
Look at this:
>>> l = [2, 4, 6, 8]
>>> i = iter(l) # returns list_iterator object which has next method
>>> next(i)
2
>>> next(i)
4
>>> l.insert(2, 'A')
>>> next(i)
'A'
Every time you update your original list before StopIteration
you will get the updated iterator and next
returns accordingly. That's why your loop runs infinitely.
For more on iteration and the iteration protocol you can look here.
참고URL : https://stackoverflow.com/questions/44633798/what-is-the-meaning-of-list-in-this-code
'program tip' 카테고리의 다른 글
$ export에 해당하는 Windows (0) | 2020.12.12 |
---|---|
AWS : 구성 프로필 (MyName)을 찾을 수 없습니다. (0) | 2020.12.12 |
상대 URL 경로를 절대 경로로 확인 (0) | 2020.12.12 |
TFS가 각 프로젝트를 자체 디렉터리에 출력하도록하는 가장 좋은 방법은 무엇입니까? (0) | 2020.12.12 |
OkHttp Post Body as JSON (0) | 2020.12.11 |