How to transform string of space-separated key,value pairs of unique words into a dict

前端 未结 9 899
走了就别回头了
走了就别回头了 2020-11-30 14:22

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         


        
相关标签:
9条回答
  • 2020-11-30 14:44

    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]))
    
    0 讨论(0)
  • 2020-11-30 14:47

    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'}
    >>> 
    
    0 讨论(0)
  • 2020-11-30 14:48

    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.

    0 讨论(0)
提交回复
热议问题