I want to count a given list like:
list = [1 , 1, 2, 2, 4, 2, 3, 3]
and the result will be:
2122141223
So what the code does is count by order how many times the x number is in row. In the example above there is 1 and then another 1, so = 2 (the number of occurence) 1 (the number itself)
list = [1, 1, 2, 1, 4, 6]
i = 0
n = len(list)
c = 1
list2 =[]
while i in range(0, n) and c in range (1 , n):
if list[i] == list[i+1]:
listc= i+c
listx = str(listc)
list2.insert(i, i+c)
i += 1
c += 1
else:
f = i + 1
i += 1
c += 1
That's what I've done and I don't know how to continue.
What I'm trying to do is a loop that checks if the number are identical, if they are they will continue to the next number until it runs with different number.
You can use the Python groupby function as follows:
from itertools import groupby
my_list = [1, 1, 2, 2, 4, 2, 3, 3]
print ''.join('{}{}'.format(len(list(g)), k) for k,g in groupby(my_list))
Giving you the following output:
2122141223
The k gives you the key (e.g. 1, 2, 4, 2, 3), and the g gives an iterator. By converting this to a list, its length can be determined.
Or without using the groupby function, you could do the following:
my_list = [1, 1, 2, 2, 4, 2, 3, 3]
current = my_list[0]
count = 1
output = []
for value in my_list[1:]:
if value == current:
count += 1
else:
output.append('{}{}'.format(count, current))
current = value
count = 1
output.append('{}{}'.format(count, current))
print ''.join(output)
Related
I'm having a problem returning the sum. I keep getting zero.
I commented the print results for better understanding. Again, my code is returning 0, and not 11.
A = [1, 5, 2, 1, 4, 0]
def solution(A):
start = [i - j for i, j in enumerate(A)]
start.sort() #[-4, -1, 0, 0, 2, 5]
for i in range(0, len(A)):
pair = 0
end = i + A[i] #1, 6, 4, 4, 8, 5
count = bisect_right(start, end) #4, 6, 5, 5, 6, 6
count_1 = count-1 #3, 5, 4, 4, 5, 5
count_2 = count_1 - i #3, 4, 2, 1, 1, 0
pair += count_2 #??????? I need the above added together like this 3+4+2+1+1+0 since
that's the answer.
return pair
print(solution(A))
As you've written in the comments, the last count2 is zero.
You're adding zero to zero, the loop ends, and you return zero.
You need to start the counter outside the loop, or you can sum outside too, like so
counts = []
for i, x in enumerate(A):
counts.append(bisect_right(start, i + x) - 1 - i)
return sum(counts)
Which could be rewritten
return sum(bisect_right(start, i + x) - 1 - i for for i, x in enumerate(A))
I have a list with 24 million elements and I want to increment count of each element iteratively and store the count in another list in faster way. For example, my list is:
a=['bike','bike','jeep','horse','horse','horse','flight','flight','cycle']
My expected output is
[1, 2, 1, 1, 2, 3, 1, 2, 1]
The code i used is
z=[]
for i in a:
z.append(a.count(i))
But my output is bit different
[2, 2, 1, 3, 3, 3, 2, 2, 1]
My order of this newly created list is also important and should be based on my list(a). Any help is really appreciated.
Based on your expected output, since you need the count of elements till that index of the list at which you are iterating at that point of time, the below code should work:
from collections import defaultdict
a=['bike','bike','jeep','horse','horse','horse','flight','flight','cycle']
a_dict = defaultdict(int)
a_output = []
for x in a:
a_dict[x] += 1
a_output.append(a_dict[x])
print(a_output)
Output:
[1, 2, 1, 1, 2, 3, 1, 2, 1]
Here is one solution -
a=['bike','bike','jeep','horse','horse','horse','flight','flight','cycle']
countArr = []
temp = {}
for i in a:
if i in temp:
temp[i]+=1
countArr.append(temp.get(i))
else:
temp[i] = 1
countArr.append(temp.get(i))
You could use a dictionary and a for loop to accomplish this:
counts = {}
a = ['bike','bike','jeep','horse','horse','horse','flight','flight','cycle']
z = []
for i in a:
if i in counts:
counts[i] += 1
else:
counts[i] = 1
z.append(counts[i])
print(z)
# [1, 2, 1, 1, 2, 3, 1, 2, 1]
You can also do this fun hacky thing with a list comprehension, which exploits the evaluation order of tuples and does essentially the same as the above for loop but condensed into one line:
counts = {}
z = [(counts.__setitem__(i, counts[i] + 1 if i in counts else 1), counts[i])[1] for i in a]
print(z)
# [1, 2, 1, 1, 2, 3, 1, 2, 1]
you can use sub-array count :
a=['bike','bike','jeep','horse','horse','horse','flight','flight','cycle']
z=[]
i = 0
while i < len(a):
#print(a[0:i])
#print(a[i])
z.append(a[0:i].count(a[i]) + 1)
i+= 1
print(z)
I am given a 1D array of numbers.
I need to go through the array adding each consecutive element to form a sum. Once this sum reaches a certain value, it forms the first element of a new array. The sum is then reset and the process repeats, thus iterating over the whole array.
For example if given:
[1, 3, 4, 5, 2, 5, 3]
and requiring the minimum sum to be 5,
the new array would be:
[8, 5, 7]
Explicity: [1 + 3 + 4, 5, 2 + 5]
I then also need to keep a record of the way the elements were combined for that particular array: I need to be to take a different array of the same length and combine the elements in the same way as above.
e.g. give the array
[1, 2, 1, 1, 3, 2, 1]
I require the output
[4, 1, 5]
Explicity: [1 + 2 + 1, 1, 3 + 2]
I have accomplished this with i loops and increment counters, but it is very ugly. The array named "record" contains the number of old elements summed to make each element of the new array i.e. [3, 1, 2]
import numpy as np
def bin(array, min_sum):
num_points = len(array)
# Create empty output.
output = list()
record = list()
i = 0
while i < num_points:
sum = 0
j = 0
while sum < min_sum:
# Break out if it reaches end of data whilst in loop.
if i+j == num_points:
break
sum += array[i+j]
j += 1
output.append(sum)
record.append(j)
i += j
# The final data point does not reach the min sum.
del output[-1]
return output
if __name__ == "__main__":
array = [1, 3, 4, 5, 2, 5, 3]
print bin(array, 5)
I would advice you to simply walk through the list. Add it to an accumulator like the_sum (do not use sum, since it is a builtin), and in case the_sum reaches a number higher than the min_sum, you add it, and reset the_sum to zero. Like:
def bin(array, min_sum):
result = []
the_sum = 0
for elem in array:
the_sum += elem
if the_sum >= min_sum:
result.append(the_sum)
the_sum = 0
return result
The lines where the accumulator is involved, are put in boldface.
I leave combining the other array the same way as an exercise, but as a hint: use an additional accumulator and zip to iterate over both arrays concurrently.
Here is a straightforward solution. which computes a list of boolean values where the value is true when accumulated element equals or exceeds the target value and calc computes an accumulation using this list.
def which(l, s):
w, a = [], 0
for e in l:
a += e
c = (a >= s)
w.append(c)
if c:
a = 0
return w
def calc(l, w):
a = 0
for (e, c) in zip(l, w):
a += e
if c:
yield a
a = 0
here is an interactive demonstration
>>> l1 = [1, 3, 4, 5, 2, 5, 3]
>>> w = which(l1, 5)
>>> w
[False, False, True, True, False, True, False]
>>> list(calc(l1, w))
[8, 5, 7]
>>> l2 = [1, 2, 1, 1, 3, 2, 1]
>>> list(calc(l2, w))
[4, 1, 5]
You can use short solutions I found out after a long struggle with flattening arrays.
For getting bounded sums use:
f = lambda a,x,j,l: 0 if j>=l else [a[i] for i in range(j,l) if sum(a[j:i])<x]
This outputs:
>>> f = lambda a,x,j,l: 0 if j>=l else [a[i] for i in range(j,l) if sum(a[j:i])< x]
>>> a= [1, 3, 4, 5, 2, 5, 3]
>>> f(a,5,0,7)
[1, 3, 4]
>>> sum(f(a,5,0,7))
8
>>> sum(f(a,5,3,7))
5
>>> sum(f(a,5,4,7))
7
>>>
To get your records use the function:
>>> y = lambda a,x,f,j,l: [] if j>=l else list(np.append(j,np.array(y(a,x,f,j+len(f(a,x,j,l)),l))))
From here, you can get both array of records and sums:
>>> listt=y(a,5,f,0,len(a))
>>> listt
[0.0, 3.0, 4.0, 6.0]
>>> [sum(f(a,5,int(listt[u]),len(a))) for u in range(0,len(listt)-1)]
[8, 5, 7]
>>>
Now, the bit of magic you can even use it as an index-conditional boundary for the second vector:
>>> b=[1, 2, 1, 1, 3, 2, 1]
>>> [sum(f(b,5,int(listt[u]),int(listt[u+1]))) for u in range(0,len(listt)-1)]
[4, 1, 5]
>>>
I want to see the number of times that a number is greater than the number after it, in a list.
example = [2, 3, 4, 5, 7, 8, 6, 2, 3, 4, 5]
def lstCount(lst):
counter = 0
if lst[0] < lst[1]:
counter + 1
lstCount(lst[1:])
else:
lstCount(lst[1:])
return counter
lstCount(example)
This should produce 2, but I am getting list index out of range.
it = iterator(lst)
next(it, None)
count = sum(a > b for a, b in zip(lst, it))
Or simply
count = sum(a > b for a, b in zip(lst, lst[1:]))
You need to add a base case where the lst is only 1 element. Otherwise when it checks lst[1] it will be attempting to check an element that does not exist and you can get an out of bounds error. Additionally counter + 1 does nothing. I suggest simply returning the value instead of using a counter.
def lstCount(lst):
if len(lst) == 1:
return 0
elif lst[0] > lst[1]:
return 1 + lstCount(lst[1:])
return lstCount(lst[1:])
Another straight solution:
traverse first n-1 elements and compare current and next element in list.
example = [2, 3, 4, 5, 7, 8, 6, 2, 3, 4, 5]
count = 0
for i in range(len(example) - 1):#get size of example then decrease by 1
if example[i] < example[i + 1]:#visit element by index
count = count + 1
print count
Output:
8
I want to make a script. The program should get some list L with values, and natural number N.
If N>0, the list's objects move N steps to left.
If N<0, the list's objects move abs(N) to the right.
If N=0 the list remain the same...
For example: For N=1 and L=[1,2,3,4,5], the output is [2,3,4,5,1].
For same list and N=-1 the output is [5,1,2,3,4]
I actually did it using collection.deque, but I want to do this with nothing but lists, for loop and 'if'.
I have problem to understand how to make the objects move.
l = input("enter list:")
N = input("enter number of rotations:")
import collections
d = collections.deque(l)
d.rotate(-N)
print d
You can use list slicing:
def rotate(L, N):
if not L or N % len(L) == 0:
return L
return L[N % len(L):] + L[:N % len(L)]
L = [1, 2, 3, 4, 5]
for N in range(-3, 4):
print(rotate(L, N))
Output:
[3, 4, 5, 1, 2]
[4, 5, 1, 2, 3]
[5, 1, 2, 3, 4]
[1, 2, 3, 4, 5]
[2, 3, 4, 5, 1]
[3, 4, 5, 1, 2]
[4, 5, 1, 2, 3]
Note that if you use a list, the time complexity of a rotation is linear to the number of elements in the list in general, since you have to move all existing elements. deque.rotate(), on the other hand, is O(k), with k being the number of steps. Therefore, if you need to rotate more than once deque.rotate() is the way to go.
This works:
result = l[N % len(l):]+l[:N % len(l)]
If using numpy is an option for you, there is a method called roll, which you might want to have a look at:
import numpy as np
array = np.arange(1, 6) # 1 to 5
print array
print np.roll(array, 0)
print np.roll(array, 2)
print np.roll(array, -2)
print np.roll(array, 17)
The result is as expected:
[1 2 3 4 5]
[1 2 3 4 5]
[4 5 1 2 3]
[3 4 5 1 2]
[4 5 1 2 3]
If you're after simple lists here's how you can do it in Python 3 (based on your P2 example).
L = list(map(int, input("Enter numbers: ").split(" ")))
N = int(input("Enter how many rotations to perform: "))
print(L[N:] + L[:N])
If you don't want to create new list, you can try in-place reverse,
def reverse(nums, start, end):
i = start
j = end - 1
while i < j:
tmp = nums[i]
nums[i] = nums[j]
nums[j] = tmp
i += 1
j -= 1
def rotate(nums, n):
if n == 0:
return nums
length = len(nums)
if n < 0:
n = length + n
reverse(nums, 0, n)
reverse(nums, n, length)
reverse(nums, 0, length)
return nums
>>> rotate([1, 2, 3, 4, 5], 1)
[2, 3, 4, 5, 1]
>>> rotate([1, 2, 3, 4, 5], -1)
[5, 1, 2, 3, 4]
thank you all ! :)
your answers are great and very useful for me.
here is my solution for this question (given that I do these scripts for a basic python course for biologists):
L = input('Enter list of numbers, please: ')
N = input('Enter how many places to rotate: ')
L1 = L[N:]
L2 = L[:N]
L = L1 + L2
print L