I\'ve got a string with words that are separated by spaces (all words are unique, no duplicates). I turn this string into list:
s = \"#one cat #two dogs #th
The problem you're encountering is the result of modifying a list while iterating over it. When an item is removed, everything after it gets moved forward by one index, but the iterator does not account for the change and continues by incrementing the index it last accessed. The iterator thus skips every second element in the list, which is why you're left with half the number of elements.
The simplest direct solution to your problem is to iterate over a copy of out
, using slice notation:
for x in out[:]:
# ...
out.remove(x)
However, there is a deeper question here: why do you need to remove items from the list at all? With your algorithm, you are guaranteed to end up with an empty list, which is of no use to you. It would be both simpler and more efficient to just iterate over the list without removing items.
When you're done with the list (after the for-loop block) you can explicitly delete it (using the del
keyword) or simply leave it for Python's garbage collection system to deal with.
A further issue remains: you're combining direct iteration over a list with index-based references. The use of for x in out
should typically be restricted to situations where you want to access each element independently of the others. If you want to work with indices, use for i in range(len(out))
and access elements with out[i]
.
Furthermore, you can use a dictionary comprehension to accomplish your entire task in a one-line pythonic expression:
my_dictionary = {out[i]: out[i + 1] for i in range(len(out)) if "#" in out[i]}
Another pythonic alternative would be to make use of the fact that each even-numbered element is a key, and each odd-numbered element is a value (you'd have to assume that the list result of str.split()
consistently follows this pattern), and use zip
on the even and odd sub-lists.
my_dictionary = dict(zip(out[::2], out[1::2]))
I believe you want following.
>>> a = '#one cat #two dogs #three birds'
>>> b = { x.strip().split(' ')[0] : x.strip().split(' ')[-1] for x in a.strip().split('#') if len(x) > 0 }
>>> b
{'three': 'birds', 'two': 'dogs', 'one': 'cat'}
Or even better
>>> b = [ y for x in a.strip().split('#') for y in x.strip().split(' ') if len(x) > 0 ]
>>> c = { x: y for x,y in zip(b[0::2],b[1::2]) }
>>> c
{'three': 'birds', 'two': 'dogs', 'one': 'cat'}
>>>
If you just need to clear the list,
use
out = []
or
out.clear()
Anyway, that you said is because remove
function of list affects list.
out = ['a', 'b', 'c', 'd', 'e', 'f']
for x in out:
out.remove(x)
print(x)
then result is shown below:
a c e
It is exactly half of full list. So, in your case, you got 96(half of 192) from 192.