Constructing Lists - python

I'm new to Python and I came across the following query. Can anyone explain why the following:
[ n**2 for n in range(1, 6)]
gives:
[1, 4, 9, 16, 25]

It is called a list comprehension. What is happening is similar to the following:
results = []
for n in range(1,6):
results.append(n**2)
It therefore iterates through a list containing the values [0, 1, 2, 3, 4, 5] and squares each value. The result of the squaring is then added to the results list, and you get back the result you see (which is equivalent to 0**2, 1**2, 2**2, etc., where the **2 means 'raised to the second power').
This structure (populating a list with values based on some other criteria) is a common one in Python, so the list comprehension provides a shorthand syntax for allowing you to do so.

Breaking it down into manageable chunks in the interpreter:
>>> range(1, 6)
[1, 2, 3, 4, 5]
>>> 2 ** 2 # `x ** 2` means `x * x`
4
>>> 3 ** 2
9
>>> for n in range(1, 6):
...   print n
1
2
3
4
5
>>> for n in range(1, 6):
... print n ** 2
1
4
9
16
25
>>> [n ** 2 for n in range(1, 6)]
[1, 4, 9, 16, 25]

So that's a list comprehension.
If you break it down into 3 parts; separated by the words: 'for' and 'in' ..
eg.
[ 1 for 2 in 3 ]
Probably reading it backwards is easiest:
3 - This is the list of input into the whole operation
2 - This is the single item from the big list
1 - This is the operation to do on that item
part 1 and 2 are run multiple times, once for each item in the list that part 3 gives us. The output of part 1 being run over and over, is the output of the whole operation.
So in your example:
3 - Generates a list: [1, 2, 3, 4, 5] -- Range runs from the first param to one before the second param
2 - 'n' represents a single number in that list
1 - Generates a new list of n**2 (n to the power of 2)
So an equivalent code would be:
result = []
for n in range(1, 6):
result.append(n**2)
Finally breaking it all out:
input = [1, 2, 3, 4, 5]
output = []
v = input[0] # value is 1
o = v**2 # 1 to the power of two is 1
output.append(o)
v = input[1] # value is 2
o = v**2 # 2 to the power of two = (2*2) = 4
output.append(o)
v = input[2] # value is 3
o = v**2 # 3 to the power of two is = (3*3) = 9
output.append(o)
v = input[3] # value is 4
o = v**2 # 4 to the power of two is = (4*4) = 16
output.append(o)
v = input[4] # value is 5
o = v**2 # 5 to the power of two is = (5*5) = 25
output.append(o)

Related

Finding number from list that respects conditions

I need to code a script that chooses a number from a user input (list) depending on two conditions:
Is a multiple of 3
Is the smallest of all numbers
Here is what I've done so far
if a % 3 == 0 and a < b:
print (a)
a = int(input())
r = list(map(int, input().split()))
result(a, r)
The problem is I need to create a loop that keeps verifying these conditions for the (x) number of inputs.
It looks like you want a to be values within r rather than its own input. Here's an example of iterating through r and checking which numbers are multiples of 3, and of finding the minimum of all the numbers (not necessarily only those which are multiples of 3):
r = list(map(int, input().split()))
for a in r:
if a % 3 == 0:
print(f"Multiple of 3: {a}")
print(f"Smallest of numbers: {min(r)}")
1 2 3 4 5 6 7 8 9 0
Multiple of 3: 3
Multiple of 3: 6
Multiple of 3: 9
Multiple of 3: 0
Smallest of numbers: 0
Doing this in one line – or through generators – can improve performance through optimizing memory allocation:
my_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# The following is a generator
# Also: you need to decide if you want 0 to be included
all_threes = (x for x in my_list if x%3==0)
min_number = min(my_list)

I need to python code to get sum of some of its k consecutive numbers in a list in python

#Given array of integers, find the sum of some of its k consecutive elements.
#Sample Input:
#inputArray = [2, 3, 5, 1, 6] and k = 2
#Sample Output:
#arrayMaxConsecutiveSum(inputArray, k) = 8
#Explaination:
#All possible sums of 2 consecutive elements are:
#2 + 3 = 5;
#3 + 5 = 8;
#5 + 1 = 6;
#1 + 6 = 7.
#Thus, the answer is 8`
Your question is not clear but assuming you need a function to return the sum of the highest pair of numbers in your list:
def arrayMaxConsecutiveSum(inputArray, k):
groups = (inputArray[pos:pos + k] for pos in range(0, len(inputArray), 1)) # iterate through array creating groups of k length
highest_value = 0 # start highest value at 0
for group in groups: # iterate through groups
if len(group) == k and sum(group) > highest_value: # if group is 2 numbers and value is higher than previous value
highest_value = sum(group) # make new value highest
return highest_value
inputArray = [2, 3, 5, 1, 6]
print(arrayMaxConsecutiveSum(inputArray, 2))
#8

How do I fix this program that adds up all the integers in a list except the one that equals said sum?

I am trying to solve a problem where I have to enter several integers as an input (seperated by a whitespace), and print the integer that is the sum of all the OTHER integers.
So e.g.:
1 2 3 would give: 3, because 3 = 1 + 2
1 3 5 9 would give: 9, because 5 + 3 + 1 = 9
This is the code I currently have:
x = input().split(" ")
x = [int(c) for c in x]
y = 0
for i in range(len(x)-1):
y += x[i]
del x[i]
z = sum(x)
if y == z:
print(y)
break
else:
x.insert(i,y)
As the output, it just gives nothing no matter what.
Does anyone spot a mistake? I'd be ever greatful as I'm just a beginner who's got a lot to learn :)
(I renamed your strange name x to numbers.)
numbers = input().split()
numbers = [int(i) for i in numbers]
must_be = sum(numbers) / 2
if must_be in numbers:
print(int(must_be))
The explanation:
If there is an element s such that s = (sum of other elements),
then (sum of ALL elements) = s + (sum of other elements) = s + s = 2 * s.
So s = (sum of all elements) / 2.
If the last number entered is always the sum of previous numbers in the input sequence. Your problem lies with the x.insert(i, y) statement. For example take the following input sequence:
'1 2 5 8'
after the first pass through the for loop:
i = 0
z = 15
x = [1, 2, 5, 8]
y = 1
after the second pass through the for loop:
i = 1
z = 14
x = [1, 3, 5, 8]
y = 3
after the third pass through the for loop:
i = 2
z = 12
x = [1, 3, 8, 8]
y = 8
and the for loop completes without printing a result
If it's guaranteed that one of the integers will be the sum of all other integers, can you not just sort the input list and print the last element (assuming positive integers)?
x = input().split(" ")
x = [int(c) for c in x]
print(sorted(x)[-1])
I think this is a tricky question and can be done in quick way by using a trick
i.e create a dictionary with all the keys and store the sum as value like
{1: 18, 3: 18, 5: 18, 9: 18}
now iterate over dictionary and if val - key is in the dictionary then boom that's the number
a = [1, 3, 5, 9]
d = dict(zip(a,[sum(a)]*len(a)))
print([k for k,v in d.items() if d.get(v-k, False)])

Show the number that appears the most times in a row

How to code a program that shows me the item that appears most side-by-side?
Example:
6 1 6 4 4 4 6 6
I want four, not six, because there are only two sixes together.
This is what I tried (from comments):
c = int(input())
h = []
for c in range(c):
h.append(int(input()))
final = []
n = 0
for x in range(c-1):
c = x
if h[x] == h[x+1]:
n+=1
while h[x] != h[c]:
n+=1
final.append([h[c],n])
print(final)
Depends on what exactly you want for an input like
lst = [1, 1, 1, 2, 2, 2, 2, 1, 1, 1]
If you consider the four 2 the most common, because it's the longest unbroken stretch of same items, then you can groupby same values and pick the one with max len:
max((len(list(g)), k) for k, g in itertools.groupby(lst))
# (4, 2) # meaning 2 appeared 4 times
If you are interested in the element that appears the most often next to itself, you can zip the list to get pairs of adjacent items, filter those that are same, pass them through a Counter, and get the most_common:
collections.Counter((x,y) for (x,y) in zip(lst, lst[1:]) if x == y).most_common(1)
# [((1, 1), 4)] # meaning (1,1) appeared 4 times
For your example of 6 1 6 4 4 4 6 6, both will return 4.
maxcount=0; //store maximum number item side by side
num=-1; //store element with max count
for i=0 to n //loop through your array
count=0;
in=i;
while(arr[in++]==arr[i]){//count number of side by side same element
count++;
}
maxcount=max(maxcount,count);
num= maxcount==count? arr[i]:num;
i=in-1;
endfor;

Get value at list/array index or "None" if out of range in Python

Is there clean way to get the value at a list index or None if the index is out or range in Python?
The obvious way to do it would be this:
if len(the_list) > i:
return the_list[i]
else:
return None
However, the verbosity reduces code readability. Is there a clean, simple, one-liner that can be used instead?
Try:
try:
return the_list[i]
except IndexError:
return None
Or, one liner:
l[i] if i < len(l) else None
Example:
>>> l=list(range(5))
>>> i=6
>>> print(l[i] if i < len(l) else None)
None
>>> i=2
>>> print(l[i] if i < len(l) else None)
2
I find list slices good for this:
>>> x = [1, 2, 3]
>>> a = x [1:2]
>>> a
[2]
>>> b = x [4:5]
>>> b
[]
So, always access x[i:i+1], if you want x[i]. You'll get a list with the required element if it exists. Otherwise, you get an empty list.
If you are dealing with small lists, you do not need to add an if statement or something of the sorts. An easy solution is to transform the list into a dict. Then you can use dict.get:
table = dict(enumerate(the_list))
return table.get(i)
You can even set another default value than None, using the second argument to dict.get. For example, use table.get(i, 'unknown') to return 'unknown' if the index is out of range.
Note that this method does not work with negative indices.
Combining slicing and iterating
next(iter(the_list[i:i+1]), None)
For your purposes you can exclude the else part as None is return by default if a given condition is not met.
def return_ele(x, i):
if len(x) > i: return x[i]
Result
>>> x = [2,3,4]
>>> b = return_ele(x, 2)
>>> b
4
>>> b = return_ele(x, 5)
>>> b
>>> type(b)
<type 'NoneType'>
return the_list[i] if len(the_list) > i else None
1. if...else...
l = [1, 2, 3, 4, 5]
for i, current in enumerate(l):
following = l[i + 1] if i + 1 < len(l) else None
print(current, following)
# 1 2
# 2 3
# 3 4
# 4 5
# 5 None
2. try...except...
l = [1, 2, 3, 4, 5]
for i, current in enumerate(l):
try:
following = l[i + 1]
except IndexError:
following = None
print(current, following)
# 1 2
# 2 3
# 3 4
# 4 5
# 5 None
3. dict
suitable for small list
l = [1, 2, 3, 4, 5]
dl = dict(enumerate(l))
for i, current in enumerate(l):
following = dl.get(i + 1)
print(current, following)
# 1 2
# 2 3
# 3 4
# 4 5
# 5 None
4. List slicing
l = [1, 2, 3, 4, 5]
for i, current in enumerate(l):
following = next(iter(l[i + 1:i + 2]), None)
print(current, following)
# 1 2
# 2 3
# 3 4
# 4 5
# 5 None
5. itertools.zip_longest
from itertools import zip_longest
l = [1, 2, 3, 4, 5]
for i, (current, following) in enumerate(zip_longest(l, l[1:])):
print(current, following)
# 1 2
# 2 3
# 3 4
# 4 5
# 5 None
Using Jupyter magic command of %%timeit
init
from itertools import zip_longest
l = list(range(10000000))
Result
Method
Consume
if...else...
2.62 s
try...except...
1.14 s
dict
2.61 s
List slicing
3.75 s
itertools.zip_longest
1.14 s
Another one-liner:
return((the_list + [None] * i)[i])

Categories