For loops (novice)

前端 未结 5 760

I recently started learning Python, and the concept of for loops is still a little confusing for me. I understand that it generally follows the format for x in y

相关标签:
5条回答
  • 2021-01-18 03:37

    As you say, a for loop iterates through the elements of a list. The list can contain anything you like, so you can construct a list beforehand that contains each step.

    A for loop can also iterate over a "generator", which is a small piece of code instead of an actual list. In Python, range() is actually a generator (in Python 2.x though, range() returned a list while xrange() was the generator).

    For example:

    def doubler(x):
        while True:
            yield x
            x *= 2
    
    for i in doubler(1):
        print i
    

    The above for loop will print

    1
    2
    4
    8
    

    and so on, until you press Ctrl+C.

    0 讨论(0)
  • 2021-01-18 03:38

    Just for an alternative, how about generalizing the iterate/increment operation to a lambda function so you can do something like this:

    for i in seq(1, 9, lambda x: x*2):
        print i
    ...
    1
    2
    4
    8
    

    Where seq is defined below:

    #!/bin/python
    from timeit import timeit
    
    def seq(a, b, f):
        x = a;
        while x < b:
            yield x
            x = f(x)
    
    def testSeq():
        l = tuple(seq(1, 100000000, lambda x: x*2))
        #print l
    
    def testGen():
        l = tuple((2**x for x in range(27)))
        #print l
    
    testSeq();
    testGen();
    
    print "seq", timeit('testSeq()', 'from __main__ import testSeq', number = 1000000)
    print "gen", timeit('testGen()', 'from __main__ import testGen', number = 1000000)
    

    The difference in performance isn't that much:

    seq 7.98655080795
    gen 6.19856786728
    

    [EDIT]

    To support reverse iteration and with a default argument...

    def seq(a, b, f = None):
        x = a;
        if b > a:
            if f == None:
                f = lambda x: x+1
            while x < b:
                yield x
                x = f(x)
        else:
            if f == None:
                f = lambda x: x-1
            while x > b:
                yield x
                x = f(x)
    
    for i in seq(8, 0, lambda x: x/2):
        print i
    

    Note: This behaves differently to range/xrange in which the direction </> test is chosen by the iterator sign, rather than the difference between start and end values.

    0 讨论(0)
  • 2021-01-18 03:43

    Bear in mind that the 'list' part of the Python can be any iterable sequence.

    Examples:

    A string:

    for c in 'abcdefg':
       # deal with the string on a character by character basis...
    

    A file:

    with open('somefile','r') as f:
        for line in f:
             # deal with the file line by line
    

    A dictionary:

    d={1:'one',2:'two',3:'three'}
    for key, value in d.items():
       # deal with the key:value pairs from a dict
    

    A slice of a list:

    l=range(100)
    for e in l[10:20:2]:
        # ever other element between 10 and 20 in l 
    

    etc etc etc etc

    So it really is a lot deeper than 'just some list'

    As others have stated, just set the iterable to be what you want it to be for your example questions:

     for e in (i*i for i in range(10)):
         # the squares of the sequence 0-9...
    
     l=[1,5,10,15]
     for i in (i*2 for i in l):
         # the list l as a sequence * 2...
    
    0 讨论(0)
  • 2021-01-18 03:53

    You can use a generator expression to do this efficiently and with little excess code:

    for i in (2**x for x in range(10)): #In Python 2.x, use `xrange()`.
        ...
    

    Generator expressions work just like defining a manual generator (as in Greg Hewgill's answer), with a syntax similar to a list comprehension. They are evaluated lazily - meaning that they don't generate a list at the start of the operation, which can cause much better performance on large iterables.

    So this generator works by waiting until it is asked for a value, then asking range(10) for a value, doubling that value, and passing it back to the for loop. It does this repeatedly until the range() generator yields no more values.

    0 讨论(0)
  • 2021-01-18 03:54

    You will want to use list comprehensions for this

    print [x**2 for x in xrange(10)] # X to the 2nd power.
    

    and

    print [x**x for x in xrange(10)] # X to the Xth power.
    

    The list comprehension syntax is a follows:

    [EXPRESSION for VARIABLE in ITERABLE if CONDITION]
    

    Under the hood, it acts similar to the map and filter function:

    def f(VARIABLE): return EXPRESSION
    def c(VARIABLE): return CONDITION
    
    filter(c, map(f, ITERABLE))
    

    Example given:

    def square(x): return x**2
    
    print map(square, xrange(10))
    

    and

    def hypercube(x): return x**x
    
    print map(hypercube, xrange(10))
    

    Which can be used as alternative approach if you don't like list comprehensions. You could as well use a for loop, but that would step away from being Python idiomatic...

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