简体   繁体   中英

Best way to perform calculations on a list/tuple in Python 3x

I wrote this program that will tell you the two multiples factors of your input. Ex. if I were to input 35 (a semiprime), the program would print 5 and 7, which are the two prime numbers that multiply to 35.

But I am wondering if there is a more concise or pythonic way to iterate through this tuple so I wouldn't have to code all those "elif" statements you see below.

Also it would be great if I didn't need to rely on any external libraries.

# multiples of semiprimes 4 - 49
tuple1 = ( 2, 3, 5, 7 )

# tuple 1 calculations
while True:

        try:
                semiprime = int(input('Enter Semiprime: '))

        except ValueError:
                print('INPUT MUST BE AN INTEGER')
                continue

        # index 0 - 3
        if (tuple1[0]) * (tuple1[0]) == semiprime:
                print((tuple1[0]), (tuple1[0]))

        elif (tuple1[0]) * (tuple1[1]) == semiprime:
                print((tuple1[0]), (tuple1[1]))

        elif (tuple1[0]) * (tuple1[2]) == semiprime:
                print((tuple1[0]), (tuple1[2]))

        elif (tuple1[0]) * (tuple1[3]) == semiprime:
                print((tuple1[0]), (tuple1[3]))

        # index 1 - 3
        elif (tuple1[1]) * (tuple1[0]) == semiprime:
                print((tuple1[1]), (tuple1[0]))

        elif (tuple1[1]) * (tuple1[1]) == semiprime:
                print((tuple1[1]), (tuple1[1]))

        elif (tuple1[1]) * (tuple1[2]) == semiprime:
                print((tuple1[1]), (tuple1[2]))

        elif (tuple1[1]) * (tuple1[3]) == semiprime:
                print((tuple1[1]), (tuple1[3]))

        # index 2 - 3
        elif (tuple1[2]) * (tuple1[0]) == semiprime:
                print((tuple1[2]), (tuple1[0]))

        elif (tuple1[2]) * (tuple1[1]) == semiprime:
                print((tuple1[2]), (tuple1[1]))

        elif (tuple1[2]) * (tuple1[2]) == semiprime:
                print((tuple1[2]), (tuple1[2]))

        elif (tuple1[2]) * (tuple1[3]) == semiprime:
                print((tuple1[2]), (tuple1[3]))

        #index 3 - 3
        elif (tuple1[3]) * (tuple1[0]) == semiprime:
                print((tuple1[3]), (tuple1[0]))

        elif (tuple1[3]) * (tuple1[1]) == semiprime:
                print((tuple1[3]), (tuple1[1]))

        elif (tuple1[3]) * (tuple1[2]) == semiprime:
                print((tuple1[3]), (tuple1[2]))

I hinted at this in my comment, but realized just the link to the function docs may not be enough.

Here's how you could write your code using itertools.combinations_with_replacement :

from itertools import combinations_with_replacement

# multiples of semiprimes 4 - 49
tuple1 = ( 2, 3, 5, 7 )

# tuple 1 calculations
while True:

    try:
        semiprime = int(input('Enter Semiprime: '))

    except ValueError:
        print('INPUT MUST BE AN INTEGER')
        continue

    for (x,y) in combinations_with_replacement(tuple1, 2):
        if x * y == semiprime:
            print(x,y)

Much nicer, IMO :)

Edit : A previous version used itertools.combinations which wouldn't yield (x,y) pairs with the same value (eg (x,y) = (2,2) would never happen). combinations_with_replacement allows for duplicates. Thanks to @Copperfield for pointing this out.

While jedwards demonstrates the most Pythonic approach - using the itertools library which you will come to know and love- here is the more "classic" approach using for-loops for the pattern you want. I bring it up because as a programming beginner, it is important to know this basic, imperative idiom:

>>> tuple1 = (2,3,5,7)
>>> for i in range(len(tuple1)):
...   for j in range(i+1, len(tuple1)):
...     print(tuple1[i], tuple1[j])
... 
2 3
2 5
2 7
3 5
3 7
5 7
>>> 

Thus, your code would be shortened to:

for i in range(len(tuple1)):
    for j in range(i+1, len(tuple1)):
        if tuple1[i] * tuple1[j] == semiprime
            print(tuple1[i], tuple1[j])

Even though @ jedwards solution is great, ( as well as concise/pythonic ); one other possible solution:

def prime_multiples(l,t ):  
    for i in l:  # Iterate over our list.
        for j in t:  # Iterate over the tuple of prime factors.
            #  We check to see that we can divide without a remainder with our factor,
            #  then check to see if that factor exists in our tuple.
            if i%j == 0 and i/j in t:
                print "Prime factors: {} * {} = {}".format(j, i/j, i)
                break  # We could go not break to print out more options.

Sample output:

l = [4, 6, 9, 10, 14, 15, 21, 22, 25, 26, 33, 34, 35, 38, 39, 46, 49]
t = ( 2, 3, 5, 7 )
prime_multiples(l, t)
>>> Prime factors: 2 * 2 = 4
... Prime factors: 2 * 3 = 6
... Prime factors: 3 * 3 = 9
... Prime factors: 2 * 5 = 10
... Prime factors: 2 * 7 = 14
... Prime factors: 3 * 5 = 15
... Prime factors: 3 * 7 = 21
... Prime factors: 5 * 5 = 25
... Prime factors: 5 * 7 = 35
... Prime factors: 7 * 7 = 49

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM