Why are arbitrary target expressions allowed in for-loops?

后端 未结 4 1448
臣服心动
臣服心动 2020-12-12 20:14

I accidentally wrote some code like this:

foo = [42]
k = {\'c\': \'d\'}

for k[\'z\'] in foo:  # Huh??
    print k

But to my surprise, this

4条回答
  •  北荒
    北荒 (楼主)
    2020-12-12 21:09

    The following code would make sense, right?

    foo = [42]
    for x in foo:
        print x
    

    The for loop would iterate over the list foo and assign each object to the name x in the current namespace in turn. The result would be a single iteration and a single print of 42.

    In place of x in your code, you have k['z']. k['z'] is a valid storage name. Like x in my example, it doesn't yet exist. It is, in effect, k.z in the global namespace. The loop creates k.z or k['z'] and assigns the the values it finds in foo to it in the same way it would create x and assign the values to it in my example. If you had more values in foo...

    foo = [42, 51, "bill", "ted"]
    k = {'c': 'd'}
    for k['z'] in foo:
        print k
    

    would result in:

    {'c': 'd', 'z': 42}
    {'c': 'd', 'z': 51}
    {'c': 'd', 'z': 'bill'}
    {'c': 'd', 'z': 'ted'}
    

    You wrote perfectly valid accidental code. It's not even strange code. You just usually don't think of dictionary entries as variables.

    Even if the code isn't strange, how can allowing such an assignment be useful?

    key_list = ['home', 'car', 'bike', 'locker']
    loc_list = ['under couch', 'on counter', 'in garage', 'in locker'] 
    chain = {}
    for index, chain[key_list[index]] in enumerate(loc_list):
        pass
    

    Probably not the best way to do that, but puts two equal length lists together into a dictionary. I'm sure there are other things more experienced programmers have used dictionary key assignment in for loops for. Maybe...

提交回复
热议问题