if i run this code:
def numbers_in_lists(string):
next_number = 0
count = 0
final_list = []
while count < len(string):
number = int(string[count])
if number > next_number:
final_list.append(number)
new = []
next_number = number
else:
new.append(number)
if new not in final_list:
final_list.append(new)
count += 1
print final_list
#testcases
string = '543987'
result = [5,[4,3],9,[8,7]]
print repr(string), numbers_in_lists(string) == result
i get this answer:
'543987' [5, [4, 3], 9, [8, 7]]
False
but if i put the number variable outside of the while loop like this:
def numbers_in_lists(string):
next_number = 0
count = 0
final_list = []
number = int(string[count])
while count < len(string):
if number > next_number:
final_list.append(number)
new = []
next_number = number
else:
new.append(number)
if new not in final_list:
final_list.append(new)
count += 1
print final_list
i get this answer:
'543987' [5, [5, 5, 5, 5, 5]]
False
I am a beginner and i have looked everywhere for the explanation as to why the number variable behaves differently outside of the loop? Also, why are the other variables ok outside of the loop but not number variable?
Any help would be much appreciated. Thankyou. :)
You declare number as
number = int(string[count])
So when
count = 0
This means that number will be the first character of your string (position [0]) converted to int. If you do not update number within your loop, it will never change. In your first version of the code, number is in your while loop.
while count < len(string):
number = int(string[count])
# more code
count += 1
Note at the end of the loop, you increment count. This means at the beginning of the next iteration, count now is incremented, so number will take on the value of the next character in your string.
A common misconception for beginners is that a variable is somehow "bound" to another variable. For example:
>>> a = 5
>>> b = a
>>> b
5
>>> a = 7
>>> b
5
See, even though a changed values from 5 to 7, b doesn't change because it is not "bound" to that variable in any way. The line b = a means "take the value from a and assign it to b" after that, b doesn't care what happens to a.
The number = int(string[count]) uses the value of count assigned outside the loop which is the first character index 0, it will never change outside the loop, so you will always get the original value appended which is the first character.
Using number = int(string[count]) inside the loop you are reassigning number to the value of the element at index count each time so you get a different part of the input string appended each time.
Once you enter the while loop any values you change that were defined outside of the loop will not change outside that loop, you must reassign the value inside the loop.
I get that you are a beginner. Here is a rewrite that should help you with some useful python idioms and constructs:
def numbers_in_lists(string):
numbers = [int(c) for c in string]
next_number = -1
final_list = []
for number in numbers:
if number > next_number:
final_list.append(number)
final_list.append([])
next_number = number
else:
final_list[-1].append(number)
final_list = [x for x in final_list if x != []]
print final_list
First, be suspicious when you have a while-loop and a counter. You can replace it with a for-loop that iterates over all the items.
Since this code operates on integers, not characters in a string, let's translate them all at once using a list comprehension:
numbers = [int(c) for c in string]
This creates a list that has all the characters translated to integers.
By setting next_number = -1, we ensure that all numbers in numbers will be greater. In particular, the first element will be greater.
When we find a number that exceeds our last maximum, next_number, we add number and a bucket to put succeeding numbers less than number into:
if number > next_number:
final_list.append(number)
final_list.append([])
next_number = number
That means when we add 5, final_list looks like this:
[5, []]
And when number is 4 and 3, they get added properly:
[5, [4]]
[5, [4, 3]]
How does that happen? This code does it:
else:
final_list[-1].append(number)
Here we do not append to final_list; we append to the last list in final_list, final_list[-1].
But what if our sequence was just 5? Then at the end of the loop, final_list would look like this:
[5, []]
In that case, we want to trim out all empty lists, so we do it like this:
final_list = [x for x in final_list if x != []]
This says, "make final_list into a list that has all elements of final_list except those that are empty lists."
Good luck with learning python. I hope you find it rewarding.
Related
I have a task to count numbers less than a given number. I understand this for most cases except ones with duplicates. So for example a list [1,2,2,3,4] I want the out put of this to be a count of 2 since it not including the middle one
One way I’ve tried this target is the number is the given number to find the less than to
count=0
for i in list:
if i< target:
count=count+1
return count
I know if I put = it will count both twos how can I fix this with what I have now and it still being a list
I would first remove duplicates like this:
res = []
[res.append(x) for x in list if x not in res]
and then you could get the number of values in the list without duplicates with the len function: len(res) or check each value to make sure it meets criteria before counting like being less then a number:
count = 0
for i in res:
if i < target: count += 1
return count
Although it might be faster to create a list of numbers that are both not duplicates and meet the criteria, and then just take the length of that list:
res = []
[res.append(x) for x in list if x not in res and x < target]
return len(res)
Put all the list items into a set and then count the number of elements less than target:
>>> a_list = [1, 2, 2, 3, 4]
>>> target = 3
>>> sum(i < target for i in set(a_list))
2
You can just change list to a set. That is, loop through a set of the list. This way you will go through each unique element once. See the code below:
count = 0
for element in set(list):
if element < target:
count += 1
print(count)
You can simply use a list comprehension:
target = 3 # can be any other number
len([x for x in set(myList) if x < target])
This question already has answers here:
Sum list values within a given range using while loop
(2 answers)
Closed 2 years ago.
i wrote this code in python:
list=[3,5,7,6,-9,5,4]
i=0
total=0
while i<len(list) and list[i] > 0:
total+=list[i]
i+=1
print(total)
and instead of getting the total of all positive numbers i only get the total of numbers that are located before the negative one, i'm not sure what i'm doing wrong, this is just my fourth code in python i'd like some help^^
That is because you have the condition that the loop ends if you encounter a negative number. You can first remove that condition from the loop.
while i<len(list):
Next, you only want to add non-negative numbers so, use a conditional statement in the loop with the condition that you want.
if list[i] > 0:
Try to understand the working of while loop. It works as long as i < len(list and list[i] > 0. When it reaches the value -9, the while loop's second condition gets false and it terminates. Hence no sum is calculated after first negative integer is encountered.
To solve this, do
lis = [3, 5, 7, 6, -9, 5, 4]
sum = 0
for i in lis:
if i > 0:
sum += i
For your while loop code, use
lis = [3, 5, 7, 6, -9, 5, 4]
i = 0
sum = 0
while i < len(lis):
if lis[i] > 0:
sum += lis[i]
i = i + 1
Also, although you can use a variable name as list, it is advised not to do so in Python as list is also a keyword.
Do not use a while loop in this case. Iteration over items in a container is easier in Python with a for loop. Plus the logic is wrong and exits the while loop early when it fails the and list[i] > 0 condition.
lst = [3,5,7,6,-9,5,4]
total = 0
for item in lst:
if item > 0:
total += item
print(total)
Also, don't use list as a variable name. That replaces the built-in list type and is called "shadowing".
You can also use a list comprehension and simplify the code even more:
lst = [3,5,7,6,-9,5,4]
total = sum([item for item in lst if item > 0])
print(total)
a program that takes a list of numbers separated with "," from the user and extracts and prints every fibonacci sequence from the list.
like this:
In: 5,6,9,3,0,1,1,2,3,8,2,9,3,0,1,1,2,3,5,98
Out:
[0,1,1,2,3]
[0,1,1,2,3,5]
i tried to use "for" loops to find the first 0 and process the program after it. like it checks and follows the list for the fibonacci sequence until it's out of the sequence, prints the list, and then looks for the next 0.
i wrote the part of the code that gets the input, but i don't know how to do the rest
numbers = input("Enter your numbers list and use comma to seperate them: ")
numlist = numbers.split(",")
numlist = [int(x) for x in numlist]
result = []
"result" is the output list (or lists).
i hope my explanations were clear. anyone can help?
Below program should work, it will check for the fibbonaci series in the list of numbers
numbers = [5,6,9,3,0,1,1,2,3,8,2,9,3,0,1,1,2,3,5,98]
first = numbers[0]
second = numbers[1]
fibbonacci = []
result = []
for number in numbers[2:]:
if first + second == number:
if not fibbonacci:
fibbonacci.extend([first, second, number])
else:
fibbonacci.append(number)
elif fibbonacci:
result.append(fibbonacci)
fibbonacci = []
first = second
second = number
print(result)
Idea is very similar to #Vuplex but can use os.path.commonprefix to remove extra code to compare two series
import os
numlist = list(map(int,input.split(',')))
answer = []
fib_series = [0,1,1,2,3,5,8,13]
answer = []
i = 0
while i < len(numlist):
if not numlist[i]:
answer.append(os.path.commonprefix([fib_series,numlist[i:]]))
i += 1
print(answer) #[[0, 1, 1, 2, 3], [0, 1, 1, 2, 3, 5]]
FIB = [0,1,1,2,3,5,8,13]
def checkSequence(numArr):
i = 0
while i < len(numArr):
if FIB[i] == int(numArr[i]):
i += 1
else:
return i
numbers = input("Enter your numbers list and use comma to seperate them: ")
numlist = numbers.split(",")
answer = list()
i = 0
while i < len(numlist):
if int(numlist[i]) == 0:
ret = checkSequence(numlist[i:])
answer.append(numlist[i:i+ret])
i += 1
As you can see, you can quite easily make a CheckSquence method to check the array splice for a squence and return the amount of entries you've found. With the answer from the checkSequence you then can create a splice for your answer list. This produces the results you've specified in your question.
EDIT: You'll need to define the Fibunacci sequence before. You can either use a static sequence like I did, or compute till a certain point and then compair against that result.
I couldn't find a question that was similar enough to mine to where I could develop a satisfactory answer.
I'm pretty new to Python (3.4.3). I am trying to add elements to an output list using a for loop by comparing each element of an input list to the next element in it.
Here is my code so far:
random_list=[1,4,5,6,7,9,19,21,22,23,24]
def count_consec(random_list):
count=1
consec_list=[]
for i in listrand:
if listrand[i] == listrand[i+1]+1:
count+=1
else:
list.append(count)
return consec_list
Basically, I want to add to consec_list[] values that represent how the length of consecutive blocks of numbers in random_list[].
I expect my output in this case to look like this:
[1,4,1,1,4]
As in, there is one singular number, followed by 4 consecutive numbers, followed by one singular number, followed by one singular number, followed by 4 consecutive numbers.
I tried many different ways and I have gotten the function to build a list, but all the elements are 1s.
You could take an approach like this:
def countlist(random_list):
retlist = []
# Avoid IndexError for random_list[i+1]
for i in range(len(random_list) - 1):
# Check if the next number is consecutive
if random_list[i] + 1 == random_list[i+1]:
count += 1
else:
# If it is not append the count and restart counting
retlist.append(count)
count = 1
# Since we stopped the loop one early append the last count
retlist.append(count)
return retlist
There are a few problems with your code, among others undefined variables, or using an element i from the list as the index of that element, but also you will get an index error for the last element, and you never add the last count to the result list.
Instead, I'd suggest using the zip(lst, lst[1:]) recipe for iterating pairs of elements from the list, and using consec[-1] to access and modify the counts already in the list.
def count_consec(lst):
consec = [1]
for x, y in zip(lst, lst[1:]):
if x == y - 1:
consec[-1] += 1
else:
consec.append(1)
return consec
random_list=[1,4,5,6,7,9,19,21,22,23,24]
print(count_consec(random_list))
# [1, 4, 1, 1, 4]
Alternatively, you could subtract the index from each element. This way, successive consecutive elements will end up being the same element. Now, you can just use itertools.groupby to group and count those elements.
>>> random_list=[1,4,5,6,7,9,19,21,22,23,24]
>>> [e-i for i, e in enumerate(random_list)]
[1, 3, 3, 3, 3, 4, 13, 14, 14, 14, 14]
>>> [sum(1 for _ in g) for _, g in itertools.groupby(_)]
[1, 4, 1, 1, 4]
The following code fixes it up. You were iterating over the elements of the list itself instead of the counter you were referencing.
random_list=[1,4,5,6,7,9,19,21,22,23,24]
def count_consec(listrand):
count=1
consec_list=[]
for i in range(len(listrand[:-1])):
if listrand[i]+1 == listrand[i+1]:
count+=1
else:
consec_list.append(count)
count=1
# Account for the last iteration
consec_list.append(count)
return consec_list
print(count_consec(random_list))
Returns this:
[1, 4, 1, 1, 4]
Here's my version
Say you had a list of numbers, which you want to loop through and count the consecutive streaks:
list_of_nums = [4,5,7,8,2,1,3,5,7,6,8,9,9,9,2,2]
You could do something like this:
streak_count = []
counter = 1
for i in range(len(list_of_nums)):
if i != (len(list_of_nums) - 1):
diff = list_of_nums[i+1] - list_of_nums[i]
if diff == 1:
counter += 1
else:
streak_count.append(counter)
counter = 1
else:
streak_count.append(counter)
So, I am trying something simple. I am trying to go through a list, which, once sorted, I can see if the next number along is higher than the previous.
If this is so, I can add it into a new list:
def longestRun(L):
'''
assume L is not empty
'''
new_list=[]
list_place=0
# we then need to iterate along the sorted List L
print L[list_place]
print L[list_place+1]
if L[list_place] < L[list_place+1]
new_list+=L[list_place]
list_place+=1
L = [1, 2, 3]
list_place = 0
new_list = []
while list_place < len(L)-1:
print L[list_place]
if L[list_place] < L[list_place+1]:
new_list.append(L[list_place])
list_place+=1
print len(new_list)
To iterate, first you need a loop statement, like while. Second, if you don't increment list_place every time you iterate, once if statement evaluates to false, it goes into loop forever.