Edit
Working!!! Thanks everyone for your input!
//= in the function is required to port from 2.x to 3.x
I am attempting to factor very large numbers in Python in a timely manner. This is working out except there is a large discrepancy in the values of the primes when multiplied together vs. the original value.
Code:
import math
x = 4327198439888438284329493298321832193892183218382918932183128863216694329
def getPrimes(n):
num = abs(n)
factor = 2
primes = []
while num > 1:
factor = getNext(num, factor)
primes.append(factor)
num /= factor
if n < -1:
primes[0] = -primes[0]
return primes
def getNext(n, f):
if n % 2 == 0:
return 2
for x in range(max(f, 3), int(math.sqrt(n) + 1), 2):
if n % x == 0:
return x
return n
values = getPrimes(x)
orig = int(1);
print(values)
for y in values:
orig *= int(y)
print("\n")
print(x)
print("\n")
print(orig)
print("\n")
print(orig-x)
Output:
[17, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
3, 83, 20845357395553.0]
4327198439888438284329493298321832193892183218382918932183128863216694329
4327198439888438374354383059307859040070974971297410068584490149575917568
90024889760986026846178791752914491136401361286359223239
???
When dividing the original number down, it is able to reach one of the prime factors just fine. This makes me confident that the factors that I am getting in the above factorization are correct.
>>> x /= 17
>>> x /= 20845357395553
>>> x /= (2**185)
>>> x /= 3
>>> x
83.0
>>> x /= 83
>>> x
1.0
>>>
TL;DR
I believe that python's code has an error with large-number (int) multiplication, or maybe I'm doing something absolutely crazy, sanity check!
Thanks!
EDIT
I did the second example code in an online python interpreter, notably 2.xx not 3.xx but I did run the code up top in 3.x as some of you noted. Redid the second operation in 3.xx and replaced. Unaware if anyone has an answer to why the code has two separate values for what should be the same.
EDIT - 7/12/2014
After further examination it appears that I have a case in which the factors are incorrect (checking with Wolfram Alpha) and I've switched algo's. I'll be testing later with long's in 2.7.
Python3 has changed what the division operator does.
In Python 2:
>>> 3 / 2
1
In Python 3:
>>> 3 / 2
1.5
>>> 3 // 2
1
Therefore, your getprimes() function should include the following code:
while num > 1:
factor = getNext(num, factor)
primes.append(factor)
num //= factor
Related
I have the following list in python3:
a = [1, 1, 1, 2, 2, 3, 3, 3, 1, 1, 1, 2, 2, 2, 4, 4, 4, 3, 3, 3, 3]
I want to have something like this as an output:
b = [1, 2, 3, 1, 2, 4, 3]
How can I do that? I have tried a = set(a) and other methods for getting rid of duplicates. But they remove all duplicates.
If you are willing to use a module, you can use itertools.groupby:
from itertools import groupby
a = [1, 1, 1, 2, 2, 3, 3, 3, 1, 1, 1, 2, 2, 2, 4, 4, 4, 3, 3, 3, 3]
output = [k for k, _ in groupby(a)]
print(output) # [1, 2, 3, 1, 2, 4, 3]
This would work:
a = [1, 1, 1, 2, 2, 3, 3, 3, 1, 1, 1, 2, 2, 2, 4, 4, 4, 3, 3, 3, 3]
b = [a[0]]
for k in a:
if k!=b[-1]:
b.append(k)
print(b)
If you comfortable with C, you may like this style:
a = [1, 1, 1, 2, 2, 3, 3, 3, 1, 1, 1, 2, 2, 2, 4, 4, 4, 3, 3, 3, 3]
b=len(a)
i=0
last_one=None
while i<b:
if a[i]==last_one:
del a[i]
b-=1
continue
else:
last_one=a[i]
i+=1
print(a)
I'm converting a working JavaScript solution for for calculating the permutations of an array over to Python, and I wanted to know why the translation doesn't work exactly the same way. Specifically, it appears as though the memo list I'm using to keep track of values is continually appended and never cleared, but I'm unsure as to what differences in Python's underpinnings cause this effect. Here's my code in Python:
def perms(input):
result = []
def permute(arr, m):
if len(arr) == 0:
print('this is m appending!: ', m)
print('=============================')
result.append(m)
else:
for i in range(len(arr)):
curr = arr.copy()
next = curr.pop(i)
m.append(next)
print('curr: ', curr)
print('next: ', next)
print('m: ', m)
permute(curr, m)
print('running')
permute(input, [])
return result
answer = perms([1,2,3])
print(answer)
and here is the output:
running
curr: [2, 3]next: 1m: [1]
curr: [3]
next: 2
m: [1, 2]
curr: []
next: 3
m: [1, 2, 3]
this is m appending!: [1, 2, 3]
=============================
curr: [2]
next: 3
m: [1, 2, 3, 3]
curr: []
next: 2m: [1, 2, 3, 3, 2]this is m appending!: [1, 2, 3, 3, 2]
=============================
curr: [1, 3]
next: 2
m: [1, 2, 3, 3, 2, 2]
curr: [3]
next: 1
m: [1, 2, 3, 3, 2, 2, 1]
curr: []
next: 3
m: [1, 2, 3, 3, 2, 2, 1, 3]
this is m appending!: [1, 2, 3, 3, 2, 2, 1, 3]
=============================
curr: [1]
next: 3
m: [1, 2, 3, 3, 2, 2, 1, 3, 3]
curr: []
next: 1
m: [1, 2, 3, 3, 2, 2, 1, 3, 3, 1]
this is m appending!: [1, 2, 3, 3, 2, 2, 1, 3, 3, 1]
=============================
curr: [1, 2]
next: 3
m: [1, 2, 3, 3, 2, 2, 1, 3, 3, 1, 3]
curr: [2]
next: 1
m: [1, 2, 3, 3, 2, 2, 1, 3, 3, 1, 3, 1]
curr: []
next: 2m: [1, 2, 3, 3, 2, 2, 1, 3, 3, 1, 3, 1, 2]this is m appending!: [1, 2, 3, 3, 2, 2, 1, 3, 3, 1, 3, 1, 2]
=============================
curr: [1]
next: 2
m: [1, 2, 3, 3, 2, 2, 1, 3, 3, 1, 3, 1, 2, 2]
curr: []
next: 1
m: [1, 2, 3, 3, 2, 2, 1, 3, 3, 1, 3, 1, 2, 2, 1]
this is m appending!: [1, 2, 3, 3, 2, 2, 1, 3, 3, 1, 3, 1, 2, 2, 1]
=============================
[[1, 2, 3, 3, 2, 2, 1, 3, 3, 1, 3, 1, 2, 2, 1], [1, 2, 3, 3, 2, 2, 1, 3, 3, 1, 3, 1, 2, 2, 1], [1, 2, 3, 3, 2, 2, 1, 3, 3, 1, 3, 1, 2, 2, 1], [1, 2, 3, 3, 2, 2, 1, 3, 3, 1, 3, 1, 2, 2, 1], [1, 2, 3, 3, 2, 2, 1, 3, 3, 1, 3, 1, 2, 2, 1], [1, 2, 3, 3, 2, 2, 1, 3, 3, 1, 3, 1, 2, 2, 1]]
As you can see, the first result ([1,2,3]) is processed as intended (as you can see where I print 'this is m appending' to the results list).However, m fails to "back out" appended items when the recursion steps backwards to execute. I'm assuming this is because Python manages the stack differently, but I'm unsure. If it's helpful, I can also post the JavaScript code and results.
If someone could explain to me why exactly this code is failing, that would be great!
Olvin's comment was correct that the issue was caused by nonlocal scoping, and Ajay's comment was a good fix for the problem - basically backing out the changes to the list manually after recursion. Here's the now-functioning code:
def perms(input):
result = []
def permute(arr, m = []):
if len(arr) == 0:
result.append(m.copy())
else:
for i in range(len(arr)):
curr = arr.copy()
nextItem = curr.pop(i)
m.append(nextItem)
permute(curr, m)
m.pop()
print('running')
permute(input)
return result
answer = perms([1,2,3])
print(answer)
As we know, pprint can be "annoying" when it's printing list of a lot of small words, since pprint can only accept of two modes: one-line of multiple small words, or multiple lines of small words on each line separately.
Is there some other python library which can print the dict like {"1" : [1] * 10, "2": [2]*100} in a pretty while still compact way?
Thanks!
Pass True as the compact argument. (Only available in Python 3.4+)
>>> pprint({"1" : [1]*10, "2": [2]*100}, compact=True)
{'1': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
'2': [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2]}
I know how to get ALL combinations of a list in Python with itertools, but what if I want to limit the amount of repeats?
So, if I have [1, 2, 3, 4, 5]
But I want to limit combinations to only 3 repeats of each item (with a fixed length of the final list, say 10):
[1, 1, 1, 2, 3, 3, 5, 5, 5, 4]
[1, 2, 3, 3, 3, 4, 5, 5, 4, 4]
[4, 4, 1, 1, 1, 5, 2, 2, 2, 3]
and so on. How do I do this?
This would work:
import random
L = [1, 2, 3, 4, 5]
L3 = L * 3
random.shuffle(L3)
L3[:10]
I don't know if there is a more elegant way but that seems to work:
from itertools import combinations_with_replacement
a = [1, 2, 3, 4, 5] # can contain letters as well
all_combinations = combinations_with_replacement(a, 10)
filtered_results = []
for current in all_combinations:
throw_away = False
for item in current:
if current.count(item) > 3:
throw_away = True
break
if not throw_away:
filtered_results.append( current )
for j in filtered_results:
print(j)
You could do it the following way: Use [1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5] and use itertools.combination(the list from above, 10). That would mean that each element occurs at most three times in a resulting list.
Example with smaller list:
Edited to ensure every combination occurs exactly once, the combinations occur in random order and, finally, every combination has a random order.
Also incorporated the idea of Mike Müller to just multiply the list by 3.
import itertools
import random
combinations = set()
for c in itertools.combinations(sorted([1, 2, 3] * 3), 5):
combinations.add(c)
shuffledCombinations = list(combinations)
random.shuffle(shuffledCombinations)
for combination in shuffledCombinations:
copiedCombination = list(combination)
random.shuffle(copiedCombination)
print copiedCombination
which will give:
[2, 1, 3, 2, 2]
[2, 2, 1, 1, 2]
[3, 3, 3, 1, 2]
[2, 2, 3, 2, 3]
[1, 2, 3, 1, 2]
[1, 1, 1, 2, 3]
[2, 1, 1, 1, 2]
[3, 3, 1, 1, 1]
[1, 3, 3, 3, 1]
[3, 2, 3, 2, 3]
[3, 2, 1, 2, 3]
[1, 1, 2, 3, 3]
i would like to know how to count in a row results from text file. I wroted this code:
from itertools import groupby
def count_runs_of(seq, val):
return sum(key == val for key, group in groupby(seq))
Example:
>>> count_runs_of([1, 2, 3, 3, 3, 1, 2, 2, 4], 3)
1
>>> count_runs_of([1, 2, 3, 3, 3, 1, 2, 2, 4, 3, 3], 3)
2
>>> count_runs_of([1, 2, 3, 3, 3, 1, 2, 2, 4, 3, 3, 9, 2, 4, 3, 3, 3], 3)
3
>>> count_runs_of([1, 2, 3, 3, 3, 1, 2, 2, 4], 2)
2
I want to know how long serie it is. For example, when i have "1" in first result, i want to also print "3" (because there was 3 x 3 in a row). Could You help me? Thank You
def count_runs_of(seq, val):
return [len(list(group)) for key, group in groupby(seq) if key == val]
Example
>>> count_runs_of([1, 2, 3, 3, 3, 1, 2, 2, 4, 3, 3], 3)
[3, 2]
You were pretty close, you get get the length of a group by looping on it using sum() and generator expression. This will return length of all such runs in the list:
>>> def count_runs_of(seq, val):
return [sum(1 for _ in g) for k, g in groupby(seq) if k == val]
...
>>> count_runs_of([1, 2, 3, 3, 3, 1, 2, 2, 4], 3)
[3]
>>> count_runs_of([1, 2, 3, 3, 3, 1, 2, 2, 4, 3, 3], 3)
[3, 2]