Related
the purpose of the below function is to return:
> f(0) returns [],
> f(1) returns [[1]]
> f(2) returns [[1], [1,2]]
> f(3) returns [[1], [1,2], [1,2,3]]
how can it be improved?
def list_generator(number: int) -> list:
if number == 0:
new_list = []
else:
temp_list = []
new_list = [0] * number
for idx, num in zip(range(len(new_list)), range(1, number + 1)):
temp_list.append(num)
new_list[idx] = list(set(temp_list))
return new_list
def f(n):
return [[x + 1 for x in range(i)] for i in range(1, n + 1)]
for n in range(6):
print(n, f(n))
# 0 []
# 1 [[1]]
# 2 [[1], [1, 2]]
# 3 [[1], [1, 2], [1, 2, 3]]
# 4 [[1], [1, 2], [1, 2, 3], [1, 2, 3, 4]]
# 5 [[1], [1, 2], [1, 2, 3], [1, 2, 3, 4], [1, 2, 3, 4, 5]]
You can use a list comprehension:
def f(number: int) -> list:
return [list(range(1, i+1)) for i in range(1, number+1)]
I will start the description of the problem with an example so that the question is clear.
List of numbers: [1,2,3,4]
How can I get each successive string: [[1],[1,2],[1,2,3],[1,2,3,4],[2],[2,3],[2,3,4],[3],[3,4],[4]]
I've been trying to solve this problem for a while and managed to get [[1, 2, 3, 4], [2, 3, 4], [3, 4], [4]] with lots of useless repetitions.
list = [1,2,3,4]
i = 0
j = 0
tempList = []
sequancesList = []
while i < len(list):
while j < len(list):
tempList.append(list[j])
sequancesList.append(tempList)
j += 1
i += 1
j = i
tempList = []
def deleteDuplicates(list):
noduplist = []
for element in list:
if element not in noduplist:
noduplist.append(element)
return noduplist
finalSequancesList = deleteDuplicates(sequancesList)
print(finalSequancesList)
Here's how to do it:
list = [1,2,3,4]
sequancesList = []
for i in range(len(list)):
tmp = []
for j in range(i,len(list)):
tmp.append(list[j])
sequancesList.append(tmp[:])
print(sequancesList)
-> [[1], [1, 2], [1, 2, 3], [1, 2, 3, 4], [2], [2, 3], [2, 3, 4], [3], [3, 4], [4]]
Here is a generator that does exactly that:
def iter_successive(input_list):
for i in range(len(input_list)):
for j in range(i+1,len(input_list)+1):
yield input_list[i:j]
>>> list(iter_successive(input_list))
[[1], [1, 2], [1, 2, 3], [1, 2, 3, 4], [2], [2, 3], [2, 3, 4], [3], [3, 4], [4]]
Comparable one-liner solution:
def iter_successive(input_list):
return (input_list[i:j] for i in range(len(input_list))
for j in range(i+1,len(input_list)+1))
Edit: As was stated in the comments, the approach below works only if the list contains whole, ascending numbers and not in other instances.
There are two ways to do this, either as a nested for-loop or a one-liner using list-comprehension. Both versions below:
Nested for-loop
nrs = list(range(1,5))
result = []
for i in nrs:
for j in range(i, max(nrs)+1):
result.append(list(range(i,j+1)))
print(result)
List-comprehension
result = [list(range(i,j+1)) for i in nrs for j in range(i, max(nrs)+1)]
print(result)
Why this code is returning [[2, 3]] instead of [[1, 2, 3], [2, 4, 6], [3, 6, 9]] ?
i = (i for i in range(1, 4))
l = [[x * y for y in i] for x in i]
print(l)
i is generator object, which means the values in it are consumed after the first iteration. In [[x * y for y in i] for x in i] you iterate over it twice, in the seconed time its empty. You can change i to list instead
i = [i for i in range(1, 4)]
l = [[x * y for y in i] for x in i]
print(l)
# output [[1, 2, 3], [2, 4, 6], [3, 6, 9]]
As already noted you created i which is exhaustable, I suggest different fix: just use range directly i.e:
i = range(1, 4)
l = [[x * y for y in i] for x in i]
print(l)
output:
[[1, 2, 3], [2, 4, 6], [3, 6, 9]]
call to range does create instance of class range which might be used multiple times for example
x = range(1,4)
print(list(x))
print(list(x))
print(list(x))
output:
[1, 2, 3]
[1, 2, 3]
[1, 2, 3]
I have a list
a=[1,2,3]
I want to perform combinations(adjacent numbers) on this list and I want multiplication each combination like below
1
1 2
2
1 2 3
2 3
3
After this, I want to perform
a) 1*1= 1
b) 1*2+2*2= 6
c) 2*2= 4
d) 1*3+2*3+3*3= 18
e) 2*3+3*3= 15
f) 3*3= 9
Expected output is
[1,2,4,18,15,9]
Here is my attempted code:
def grouper(input_list, n = 2):
for i in xrange(len(input_list) - (n - 1)):
yield input_list[i:i+n]
a = [1,2,3]
for item in [a[0:m+1] for m in range(len(a))]:
for n in range(len(item)):
result.append(item[n:])
test.append(sum([k * len(item) for k in item[n:]]))
print result
print test
output
[[1], [1, 2], [2], [1, 2, 3], [2, 3], [3]]
[1, 6, 4, 18, 15, 9]
For more length
a = [1,2,3,4]
output
[[1], [1, 2], [2], [1, 2, 3], [2, 3], [3], [1, 2, 3, 4], [2, 3, 4], [3, 4], [4]]
[1, 6, 4, 18, 15, 9, 40, 36, 28, 16]
Simple using for loops
a = [1,2,3]
tmp = []
for m in range(len(a)):
tmp.append( a[0:m +1])
result = []
test = []
for item in tmp:
for n in range(len(item)):
result.append(item[n:])
test.append(sum([k * len(item) for k in item[n:]]))
print tmp
print result
print test
Output
[[1], [1, 2], [1, 2, 3]]
[[1], [1, 2], [2], [1, 2, 3], [2, 3], [3]]
[1, 6, 4, 18, 15, 9]
Create combinations:
a = [1,2,3]
# create combinations
combinations = []
for i in range(len(a)):
for j in range(len(a)):
result = a[i:j+1]
if result:
combinations.append(result)
output:
combinations [[1], [1, 2], [1, 2, 3], [2], [2, 3], [3]]
To compute the values you want:
for values in combinations:
last_val = values[-1]
computation = ''
result = 0
for val in values:
computation += "{}*{} + ".format(val, last_val)
result += val * last_val
computation = computation[:-2] + '= {}'.format(result)
print(computation)
output:
1*1 = 1
1*2 + 2*2 = 6
1*3 + 2*3 + 3*3 = 18
2*2 = 4
2*3 + 3*3 = 15
3*3 = 9
#Vikash Singh has given an almost complete solution here:
Except that there is little mismatch with the combinations:
I have managed to correct the same:
a = [1,2,3]
combinations = []
for i in range(len(a)+1):
for j in range(i):
result = a[j:i]
if result:
combinations.append(result)
print combinations
The output will be
[[1], [1, 2], [2], [1, 2, 3], [2, 3], [3]]
And the if the list is [1,2,3,4], output will be:
[[1], [1, 2], [2], [1, 2, 3], [2, 3], [3], [1, 2, 3, 4], [2, 3, 4], [3, 4], [4]]
I hope this solves OP's problem with the combination.
I made an implementation of Longest Increasing Subsequence (LIS) algorithm, as I see it would work, but results are totally mess.
def lis():
#D = map(int, raw_input().split())
D = [3, 2, 6, 4, 5, 1]
L = [[] for i in range(len(D))]
L[0].append(D[0])
for i in range(len(D)):
for j in range(0,i):
if D[i] > D[j]:
L[i] = L[j]
L[i].append(D[i])
print L
Returned result:
[[3], [2, 6, 4, 5], [2, 6, 4, 5], [2, 6, 4, 5], [2, 6, 4, 5], [1]]
What it should be:
[[3], [2], [2, 6], [2, 4], [2, 4, 5], [1]]
As I saw in debugger when we have:
L[i] = L[j]
Not only L[i] gets new values, but other lists on the main (L) list too...
I don't know how to avoid it. It looks that lists in Python are totally different than vectors languages from C family...
I'm fighting with this for a long time. Huge beer to someone who gonna find what is wrong :(
When you state L[i] = L[j] you do not copy the content of the list, you simply copy a reference: from now on L[i] and L[j] point to the same list and changes made through L[i] will reflect when you obtain L[j].
A simply fix is simply to copy the list:
def lis():
#D = map(int, raw_input().split())
D = [3, 2, 6, 4, 5, 1]
L = [[] for i in range(len(D))]
L[0].append(D[0])
for i in range(len(D)):
for j in range(0,i):
if D[i] > D[j]:
L[i] = list(L[j])
L[i].append(D[i])
print(L)
Now hoever your algorithm does not work anymore (it was not working in the first place nevertheless). When running your (fixed) code, you get:
>>> lis()
[[3, 3], [2], [2, 6], [2, 4], [2, 4, 5], [1]]
The 3 occurs twice in the first list, you can solve this by removing the .append before the for loop. So the final version is:
def lis():
#D = map(int, raw_input().split())
D = [3, 2, 6, 4, 5, 1]
L = [[] for i in range(len(D))] #removed the next line
for i in range(len(D)):
for j in range(0,i):
if D[i] > D[j]:
L[i] = list(L[j])
L[i].append(D[i])
print(L)
Which produces:
>>> lis()
[[3], [2], [2, 6], [2, 4], [2, 4, 5], [1]]
Note: based on your comment you use python-2.7, from python-3.x there is a method called .copy() on lists that you can call.
Important Note
The solution which is above is correct but if you try it out the result can be wrong for some instances.
For example - Longest Increasing Subsequence for numbers:
5 1 4 2 3 1 2 9 1
is
1 2 3 9
But this solution won't be on your L list returned by algorithm. There will be:
1 2 9
Max element from L list is needed. Then another element from D can be appended, so we have to add one more condition, here you go the correct code:
def lis():
#D = map(int, raw_input().split())
D = [5, 1, 4, 2, 3, 1, 2, 9, 1]
L = [[] for i in range(len(D))]
for i in range(len(D)):
for j in range(0,i):
if D[i] > D[j] and len(L[i]) < len(L[j])+1: #added condition
L[i] = list(L[j])
L[i].append(D[i])
print(L)
>>lis()
[[5], [1], [1, 4], [1, 2], [1, 2, 3], [1], [1, 2], [1, 2, 3, 9], [1]]