0

Suppose I have 2 lists, for which the i-th element of the first lists corresponds to the i-th element of the second list. How can i iteratively apply elements from the 2 lists into a different function?

def GetLists(n):
    List1 = []
    List2 = []
    n = int(input("how many terms: "))
    for i in range(1,n):
        val1 = float(input("what is val1: "))
        val2 = float(input("what is the corresponding val2: "))
        List1.append(val1)
        List2.append(val2)
    return List1, List2

def newfunc(ListA, ListB, var):
    # take i-th elements from lists A and B where (a,b) are the i-th elements of A and B
    # want output = sum(a * var ** b) for index in len(A) if len(A) == len(B)

What is the most pythonic way to do this? If possible, I would like to do so without importing external modules.

Edit: I checked other solutions. The "duplicate" answer requires importing modules; I was trying to do without. Also, I am trying to do an operation that returns an output rather than print values, which complicates the use of zip beyond the level shown in the duplicate answer.

  • 2
    Are you looking for `for a, b in zip(ListA, ListB):`? Also, note that what you've posted isn't Python - case matters. – jonrsharpe Jan 09 '17 at 08:46
  • @jonrsharpe Which part isn't python (which part is case-dependent)? Please excuse my ignorance, I am still a beginner. –  Jan 09 '17 at 09:20
  • `Def` -> `def`, `For` -> `for`. If you're new, **read a tutorial**. And this is a duplicate, `zip` doesn't require an import and you can do whatever you want with `a` and `b` once you have them. – jonrsharpe Jan 09 '17 at 09:21
  • Ahhh, my careless mistake. I was typing on a mobile phone. I will edit it now. –  Jan 09 '17 at 09:22
  • As for being a duplicate, the "original" requires importing itertools. It also prints and does not do an operation on the zipped elements. –  Jan 09 '17 at 09:25
  • 1. No it doesn't, it shows an *option* that uses `itertools`. 2. So what? SO isn't a code-writing service, you are expected to be able to adapt generic answers to your specific needs. – jonrsharpe Jan 09 '17 at 09:26
  • Well, I specifically asked for an answer that does not import modules to do this. I could not adapt the methods in the "original" to my problem because I am not trying to just print my result. I don't treat SO as a code-writing service. If you feel so inclined, go to my profile and check out my other 2 most recent posts here to see how many ways I tried to this. –  Jan 09 '17 at 09:31
  • **The duplicate does not require you to import modules.** `zip` is built-in. Again, it simply shows *options*, alternative approaches, that do use imports (and only from the standard library, which you should *already have available*) and explains under what circumstances you'd use them. I see no point discussing this further. – jonrsharpe Jan 09 '17 at 09:34
  • Then I guess we both feel that way. Perhaps we should explore that; it's not clear to me what you do not understand. You keep saying it's not a duplicate because you don't want to import any modules. 1. Why don't you want to import any modules? Are you aware there's a difference between third-party modules and the standard library? What constraints are you operating under? That would be useful context to [edit] in. 2. Even so, as I keep saying, the duplicate doesn't *require* any imports. Why do you think it does? The answer you've actually accepted **uses `zip`, as the duplicate does**. – jonrsharpe Jan 09 '17 at 09:40
  • I feel that the best way to learn a program is to learn the basics. I already took a class and want to take it further on my own to apply my skills for physics research. The class I took requires that no modules be imported, and I learned a bit more this way (like how to linspace without numpy). I was not aware of differences between libraries, though now that I know I will look into it (known unknowns vs unknown unknowns). I was under the impression that itertools was an import. The use of zip isn't alien to me, I tried unsuccessfully to use it in an operation instead of printing a result. –  Jan 09 '17 at 09:46
  • `itertools` *is* an import, but from the [standard library](https://docs.python.org/3/library/), which is shipped with most Python distributions (*"batteries included"*). `numpy` is a third-party module, which you need to *install* separately before importing. – jonrsharpe Jan 09 '17 at 09:47
  • That is not say imports are not useful; they are. But I want to explore them after the basics. As proof that I tried zip and did not find it helpful, here is one of my recent posts (mentioned in comment above) --> [proof](http://stackoverflow.com/questions/41522534/how-do-i-combine-the-ith-element-of-2-lists-as-an-input-for-a-function) –  Jan 09 '17 at 09:49
  • In many cases, standard library modules *are* the basics! – jonrsharpe Jan 09 '17 at 09:50
  • I found your last few comments helpful and will investigate further. Thanks –  Jan 09 '17 at 09:50

1 Answers1

0

take i-th elements from lists A and B where (a,b) are the i-th elements of A and B

want output = sum(a * var ** b) for index in len(A) if len(A) == len(B)

Is this what you're looking for? It will zip two lists of the same length together, calculating f(a, b, i) = a[i] * var ** b[i] for some constant var and for each i where 0 <= i < len(a). It then returns the sum.

def process(list_a, list_b, var):
    if len(list_a) != len(list_b):
        raise ValueError('Lists are not equal in length')

    def combine():
        for a, b in zip(list_a, list_b):
            yield a * var ** b

    return sum(combine())

print(process([5, 2, 3], [2, 2, 3], 10))

Output

3300

This output is the result of (1 * 10 ** 2) + (2 * 10 ** 2) + (3 * 10 ** 3).

Edit

The approach above decouples the combination logic - which is the focus of your question - from the summation logic. An alternative approach which is arguably more Pythonic (as per your requirements) and a lot shorter would be to use a generator expression, as suggested in the comments for this answer:

def process(list_a, list_b, var):
    if len(list_a) != len(list_b):
        raise ValueError('Lists are not equal in length')
    
    return sum(a * var ** b for a, b in zip(list_a, list_b))

print(process([1, 2, 3], [2, 2, 3], 10))

Essentially, the expression within sum acts as an anonymous replacement for the generator function combine that I defined in the previous approach.

Community
  • 1
  • 1
Tagc
  • 8,736
  • 7
  • 61
  • 114
  • It's a different formula than the one I was looking for but I should be able to apply the same principle to mine. Thank you! Edit: The formula is corrected, works like a charm. –  Jan 09 '17 at 08:59
  • @mikey A little sleepy and misread the formula. Is the formula in my edited post correct? – Tagc Jan 09 '17 at 09:00
  • Yes, it is correct. –  Jan 09 '17 at 09:01
  • Can I ask what the downvote is for? – Tagc Jan 09 '17 at 09:14
  • I upvoted your answer because the code works. Must have been someone else. –  Jan 09 '17 at 09:18
  • @mikey No worries, I was addressing that "someone else". :) – Tagc Jan 09 '17 at 09:19
  • This is a perfect use-case for a [generator expression](https://www.python.org/dev/peps/pep-0289/). simply `return sum(a*var**b for a,b in zip(list_a, list_b))` – juanpa.arrivillaga Jan 09 '17 at 09:58
  • @juanpa.arrivillaga I considered doing that (and I knew someone would eventually make this remark). In this case I wanted to completely decouple the "zip/combination" logic (focus of question) from the summation logic to make it clearer for OP (hopefully). If you post your approach, I'll upvote it. – Tagc Jan 09 '17 at 10:01
  • @Tagc it was a suggesting for an addition to your question. I don't think there is any need for an additional answer. – juanpa.arrivillaga Jan 09 '17 at 10:04
  • @juanpa.arrivillaga Sure thing, done. – Tagc Jan 09 '17 at 10:11
  • I appreciate seeing both methods. Thanks! –  Jan 09 '17 at 11:52