Skip to content

Feature request: Complicated variable assignment in for loops #23

@MitalAshok

Description

@MitalAshok

Normally in a for loop, you just do for <variable_name> in iterable:, but you can also do use anything that is a valid assignment target (An "lvalue" in C). Like for f()(g)[t].x in seq: is perfectly valid syntax.

Here is a draft:


For what?

d = {}
for d['n'] in range(5):
    print(d)

Output:

{'n': 0}
{'n': 1}
{'n': 2}
{'n': 3}
{'n': 4}
def indexed_dict(seq):
    d = {}
    for i, d[i] in enumerate(seq):
        pass
    return d

Output:

>>> indexed_dict(['a', 'b', 'c', 'd'])
{0: 'a', 1: 'b', 2: 'c', 3: 'd'}
>>> indexed_dict('foobar')
{0: 'f', 1: 'o', 2: 'o', 3: 'b', 4: 'a', 5: 'r'}

💡 Explanation:

  • A for statement is defined in the Python grammar as:

    for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite]
    

    Where exprlist is the assignment target. This means that the equivalent of {exprlist} = {next_value} is executed for each item in the iterable.

  • Normally, this is a single variable. For example, with for i in iterator:, the equivalent of i = next(iterator) is executed before every time the block after for is.

  • d['n'] = value sets the 'n' key to the given value, so the 'n' key is assigned to a value in the range each time, and printed.

  • The function uses enumerate() to generate a new value for i each time (A counter going up). It then sets the (just assigned) i key of the dictionary. For example, in the first example, unrolling the loop looks like:

    i, d[i] = (0, 'a')
    pass
    i, d[i] = (1, 'b')
    pass
    i, d[i] = (2, 'c')
    pass
    i, d[i] = (3, 'd')
    pass

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions