Python, append within a loop - python

So I need to save the results of a loop and I'm having some difficulty. I want to record my results to a new list, but I get "string index out of range" and other errors. The end goal is to record the products of digits 1-5, 2-6, 3-7 etc, eventually keeping the highest product.
def product_of_digits(number):
d= str(number)
for integer in d:
s = 0
k = []
while s < (len(d)):
j = (int(d[s])*int(d[s+1])*int(d[s+2])*int(d[s+3])*int(d[s+4]))
s += 1
k.append(j)
print(k)
product_of_digits(n)

Similar question some time ago. Hi Chauxvive
This is because you are checking until the last index of d as s and then doing d[s+4] and so on... Instead, you should change your while loop to:
while s < (len(d)-4):

Related

Finding the highest sum of a string in a list

In this task, we creating a function called highsum. It looks at a list of strings and sums up all the numerical characters. We then return the location of the element of the list with the highest value.
For example given list highestSum([“jx72i9r”, “9ch37#r2”, “8rgku3op8”]).
We then must find [17, 21,19] which is all the numerical values added up. Because 21 is the highest value we need the function to return 1 because that is the location of 9ch37#r2 in the list.
This is what I have so far:-
def highestSum(stringList):
number= 0
for xinlist in stringList:
print(xinlist)
for yoflist in xinlist:
print (yoflist)
if yoflist in "1234567890":
number+=int(yoflist)
print(number)
The first for loop cycles through each element while the second for loop cycles through each character in the elements. My accumulator variable work but the problem is I don't know how to let it know when it moves on to a new element.
Another example highestSum([“90gw1xy3”, “12432”, “hfkvbd2”, “*&hdj!4”])
this would return 0 as it as the highest sum of digit characters.
Homemade version
Basically, we gather turn each element in the given list to there digits sum. So like [18,21,19]. Then pair this with original list using zip(). Then use .index() in order to get the corresponding index.
hilarious one-liner
def highestSum(stringList):
return stringList.index({k:v for k,v in zip([sum(list(map(int,[character for character in stringEx if character.isdigit()]))) for stringEx in stringList],stringList)}[max(summed)])
List comprehension & dict comprehension
def highestSum(stringList):
summed = [sum(list(map(int,[character for character in stringEx if character.isdigit()]))) for stringEx in stringList]
highest = max(summed)
pair = {k:v for k,v in zip(summed,stringList)}
return stringList.index(pair[highest])
print(highestSum(["jx72i9r", "9ch37#r2", "8rgku3op8"]))
Easier to understand for the human eye.
def highestSum(stringList):
summed = []
for stringEx in stringList:
gathered = []
for character in stringEx:
if character.isdigit():
gathered.append(character)
gathered = sum(list(map(int,gathered)))
summed.append(gathered)
highest = max(summed)
pair = {}
for k,v in zip(summed,stringList):
pair[k] = v
return stringList.index(pair[highest])
print(highestSum(["jx72i9r", "9ch37#r2", "8rgku3op8"]))
output
1
I have modified your code. Look at this solution. You need a condition to for the highest number in the list and a variable to keep track of its index. See solution below:
def highestSum(stringList):
index = 0
highestValue = 0
for xinlist in stringList:
number= 0
for yoflist in xinlist:
if yoflist in "1234567890":
number+=int(yoflist)
if number > highestValue:
index = stringList.index(xinlist)
highestValue = number
print(index)
stringList = ['jx72i9r', '9ch37#r2', '8rgku3op8']
highestSum(stringList)
def highestSum(stringList):
res = list()
for xinlist in stringList:
number = 0
for yoflist in xinlist:
if yoflist in "1234567890":
number += int(yoflist)
res.append(number)
# find the max position form the accumulator
maxNumPos = 0
for i in range(len(res)):
if res[i] > res[maxNumPos]:
maxNumPos = i
print(maxNumPos)
highestSum(['90gw1xy3', '12432', 'hfkvbd2', '*&hdj!4'])
I'll use list comprehension, maybe it's difficult to read.
code:
x = ["jx72i9r", "9ch37#r2", "8rgku3op8"]
x_to_int = [sum([int(char) for char in s if char.isdigit()]) for s in x]
print(x_to_int.index(max(x_to_int)))
result:
1

Python - replay values in list

Please help for task with the list in Python my logic is bad works:( .
This is full text of task: Write a program that takes a list of
numbers on one line and displays the values in a single row, are
repeated in it more than once.
To solve the problem can be useful sort method list.
The procedure for withdrawal of repetitive elements may be arbitrary.
My beginning code is :
st = (int(i) for i in input().split())
ls = []
for k in st:
if k == k + 1 and k > 1:
Task is : if we have replay value in list we must print it. We only can use sort() method and without any modules importing.
Results Examples:
Sample Input 1:
4 8 0 3 4 2 0 3
Sample Output 1:
0 3 4
Sample Input 2:
10
Sample Output 2:
Sample Input 3:
1 1 2 2 3 3
Sample Output 3:
1 2 3
This code isn't run( sort() function doesn't want sort my_list. But I must input values like my_list = (int(k) for k in input().split())
st = list(int(k) for k in input())
st.sort()
for i in range(0,len(st)-1):
if st[i] == st[i+1]:
print(str(st[i]), end=" ")
my_list = (int(k) for k in input().split())
After running this line, my_list is a generator, something that will create a sequence - but hasn't yet done so. You can't sort a generator. You either need to use []:
my_list = [int(k) for k in input().split()]
my_list.sort()
which makes my_list into a list from the start, instead of a generator, or:
my_list = list(int(k) for k in input().split()))
my_list.sort()
gather up the results from the generator using list() and then store it in my_list.
Edit: for single digits all together, e.g. 48304, try [int(k) for k in input()]. You can't usefully do this with split().
Edit: for printing the results too many times: make the top of the loop look backwards a number, like this, so if it gets to the second or third number of a repeating number, it skips over and continues on around the loop and doesn't print anything.
for i in range(0,len(st)-1):
if st[i] == st[i-1]:
continue
if st[i] == st[i+1]:
print...
st = (int(i) for i in input().split())
used = []
ls = []
for k in st:
if k in used: # If the number has shown up before:
if k not in used: ls.append(k) # Add the number to the repeats list if it isn't already there
else:
used.append(k) # Add the number to our used list
print ' '.join(ls)
In summary, this method uses two lists at once. One keeps track of numbers that have already shown up, and one keeps track of second-timers. At the end the program prints out the second-timers.
I'd probably make a set to keep track of what you've seen, and start appending to a list to keep track of the repeats.
lst = [num for num in input("prompt ").split()]
s = set()
repeats = []
for num in lst:
if num in s and num not in repeats:
repeats.append(num)
s.add(num)
print ' '.join(map(str,repeats))
Note that if you don't need to maintain order in your output, this is faster:
lst = [num for num in input("prompt ").split()]
s = set()
repeats = set()
for num in lst:
if num in s:
repeats.add(num)
s.add(num)
print ' '.join(map(str, repeats))
Although if you can use imports, there's a couple cool ways to do it.
# Canonically...
from collections import Counter
' '.join([num for num,count in Counter(input().split()).items() if count>1])
# or...
from itertools import groupby
' '.join([num for num,group in groupby(sorted(input().split())) if len(list(group))>1])
# or even...
from itertools import tee
lst = sorted(input('prompt ').split())
cur, nxt = tee(lst)
next(nxt) # consumes the first element, putting it one ahead.
' '.join({cur for (cur,nxt) in zip(cur,nxt) if cur==nxt})
this gives the answers you're looking for, not sure if it's exactly the intended algorithm:
st = (int(i) for i in input().split())
st = [i for i in st]
st.sort()
previous = None
for current in st:
if ((previous is None and current <= 1)
or (previous is not None and current == previous + 1)):
print(current, end=' ')
previous = current
>>> "4 8 0 3 4 2 0 3"
0 3 4
>>> "10"
>>> "1 1 2 2 3 3"
1 2 3
updated to:
start with st = (int(i) for i in input().split())
use only sort method, no other functions or methods... except print (Python3 syntax)
does that fit the rules?

More pythonic way to handle this logic structure

I need to break up a length of numbers into chunks of 100 and what ever is left over and then add them to a final dictionary at the end.
I am able to do it with loops but I feel I might be missing something that would make this a much cleaner and efficient operation.
l = 238 # length of list to process
i = 0 #setting up count for while loop
screenNames = {}#output dictionary
count = 0 #count of total numbers processed
while i < l:
toGet = {}
if l - count > 100:#blocks off in chunks of 100
for m in range (0,100):
toGet[count] = m
count = count + 1
else:
k = count
for k in range (0,(l - count)):#takes the remainder of the numbers
toGet[count] = k
count = count + 1
i = l # kills loop
screenNames.update(toGet)
#This logic structure breaks up the list of numbers in chunks of 100 or their
#Remainder and addes them into a dictionary with their count number as the
#index value
print 'returning:'
print screenNames
The above code works but it feels clunky does anyone have any better ways of handling this?
as far as I can see, you map a key n to the value n % 100, so this might be as well written as
screenNames = dict((i, i%100) for i in range(238))
print screenNames
Running your code, it looks like you're just doing modular arithmetic:
l = 238
sn = {}
for i in xrange(l):
sn[i] = i % 100
print sn
Or more succinctly:
l = 238
print dict((i, i % 100) for i in xrange(l))
That works by constructing a dictionary based on key-pair tuples.

Python tablecheck error

def tableCheck(elev, n, m):
tablePosCount = 0
rowPosCount = 0
for r in range(1, n):
for c in range(1, m):
if elev[r][c] > 0:
tablePosCount = tablePosCount + 1
rowPosCount = rowPosCount + 1
print 'Number of positive entries in row ', r , ' : ', rowPosCount
print 'Number of positive entries in table :', tablePosCount
return tablePosCount
elev = [[1,0,-1,-3,2], [0,0,1,-4,-1], [-2,2,8,1,1]]
tableCheck(elev, 3, 5)
I'm having some difficulty getting this code to run properly. If anyone can tell me why it might being giving me this output
Number of positive entries in row 1 : 1
Number of positive entries in row 2 : 2
Number of positive entries in row 2 : 3
Number of positive entries in row 2 : 4
Number of positive entries in row 2 : 5
Number of positive entries in table : 5
There are three things in your code that I suspect are errors, though since you don't describe the behavior you expect, it's possible that one or more of these is working as intended.
The first issue is that you print out the "row" number every time that you see a new value that is greater than 0. You probably want to unindent the print 'Number of positive entries in row ' line by two levels (to be even with the inner for loop).
The second issue is that you don't reset the count for each row, so the print statement I suggested you move will not give the right output after the first row. You probably want to move the rowPosCount = 0 line inside the outer loop.
The final issue is that you're skipping the first row and the first value of each later row. This is because your ranges go from 1 to n or m. Python indexing starts at 0, and ranges exclude their upper bound. You probably want for r in range(n) and for c in range(m), though iterating on the table values themselves (or an enumeration of them) would be more Pythonic.

Get n documents in a loop from mongodb

I have a collection of 101 documents, I need to iterate over them taking 10 collections at a time and store a value of a particular field(of 10 documents) in a list.
I tried this:
values = db.find({},{"field":1})
urls = []
count = 0
for value in values:
if(count < 10):
urls.append(value["field"])
count = count + 1
print count
else:
print urls
urls = []
urls.append(value["field"])
count = 1
It doesn't fetch the last value because it doesn't reach if condition. Any elegant way to do this and rectify ths situation?
You reset count to 0 everytime the loop restarted. Move the declaration outside the loop:
count = 0
for value in values:
If urls is already filled, this will be your only problem.
As far as I can tell, you've some data that you want to organize into batches of size 10. If so, perhaps this will help:
N = 10
values = list(db.find({},{"field":1}))
url_batches = [
[v['field'] for v in values[i:i+N]]
for i in xrange(0, len(values), N)
]

Categories

Resources