Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I am rookie with python and have question about counting pairs in array that complement to some certain number.
Example
Given an integer array A find all the complementary pairs in A that sums up to a provided value K, so for example given the array [2, 45, 7, 3, 5, 1,8,9] and an integer K = 10 the result must be 3 because the input array contains [9, 1] [7, 3] [8, 2]
Here is the code finding complementary pairs
def find_pairs(x, sum):
s = set(L)
for i in L:
diff = 10-i
s.remove(i)
if diff in s:
print i, diff
L = [2, 45, 7, 3, 5, 1, 8, 9]
sum = 10
find_pairs(L, sum)
How can I add count command at the end?
Use a simple counter variable
def find_pairs(list_, sum_):
s = set(list_)
pairs = 0
for i in list_:
diff = sum_ - i
s.remove(i)
if diff in s:
pairs += 1
return pairs
Or you can use a helper list for storing pairs if you also want to know the pairs
def find_pairs(list_, sum_):
s = set(list_)
pairs = []
for i in list_:
diff = sum_ - i
s.remove(i)
if diff in s:
pairs.append([i, diff])
return pairs
L = [2, 45, 7, 3, 5, 1, 8, 9]
pairs = find_pairs(L, 10)
print pairs
>>> [[2, 8], [7, 3], [1, 9]]
print len(pairs)
>>> 3
Using numpy:
A = np.asarray(A)
np.count_nonzero((A[None, :] + A[:, None]) == K) // 2
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 months ago.
Improve this question
I have a list [1,2,3,4,5,6,7], for each element in the list, I need to find the count of a number of elements that are less than the number. For example, the first element is 1 and there are 0 elements in the list that are less than 1, the second number is 2 and there is 1 element less than 2. So basically the output should be [0,1,2,3,4,5,6]. Need to do this in Python. Any help would be appreciated. Below is the code I've tried,
lst = [1,2,3,4,5,6,7]
count = 0
final = []
for i in range(len(lst)):
for j in range(i+1,len(lst)):
if lst[i] < lst[j]:
count = count + 1
final.append(count)
print (final)
Below is the output I got,
[6, 11, 15, 18, 20, 21, 21]
Try:
lst = [1, 2, 3, 4, 5, 6, 7]
out = [sum(vv < v for vv in lst[:i]) for i, v in enumerate(lst)]
print(out)
Prints:
[0, 1, 2, 3, 4, 5, 6]
Link to the problem: https://www.hackerrank.com/challenges/lilys-homework/forum
Summary: We have to find the minimum no. of swaps required to convert an array into sorted array. It can be sorted in ascending or descending order. So, here is the array I want to sort:
arr = [3, 4, 2, 5, 1]
We sort it in ascending order we need 4 swaps, and 2 swaps when in descending order.
For descending: -Swap 5 and 3 and then swap 3 and 2
Now, I have written a python code to solve this test case. Here is the code:
arr = [3, 4, 2, 5, 1]
arr2 = arr[:]
count = 0; count2 = 0; n = len(arr)
registry = {}
for i in range(n):
registry[arr[i]] = i
sorted_arr = sorted(arr)
#######################first for loop starts#########################
#find no. of swap required when we sort arr is in ascending order.
for i in range(n-1):
if arr[i] != sorted_arr[i]:
index = registry[sorted_arr[i]]
registry[sorted_arr[i]],registry[arr[i]]= i, index
temp = arr[i]
arr[i],arr[index]=sorted_arr[i],temp
count = count + 1
###################first for loop ends#######################
# re-initalising registry and sorted_arr for descending problem.
registry = {}
for i in range(n):
registry[arr2[i]] = i
sorted_arr = sorted(arr2)
sorted_arr.reverse()
print(arr2) #unsorted array
print(registry) #dictionary which stores the index of the array arr2
print(sorted_arr) #array in descending order.
#find no. of swap required when array is in descending order.
for i in range(n-1):
print('For iteration i = %i' %i)
if arr2[i] != sorted_arr[i]:
print('\tTrue')
index = registry[sorted_arr[i]]
registry[sorted_arr[i]],registry[arr[i]]= i, index
temp = arr2[i]
arr2[i],arr2[index]=sorted_arr[i],temp
print('\t '+ str(arr2))
count2 = count2 + 1
else:
print('\tfalse')
print('\t '+ str(arr2))
print('######Result######')
print(arr)
print(count)
print(arr2)
print(count2)
Here's the problem:
When I run the code, the second for loop i.e. the for loop for descending gives wrong value of count which is 3. But, when I comment the first for loop, i.e. the for loop for ascending it gives correct value of count which is 2.
I want to know why for loop 2 changes output when for loop 1 is present.
The output I get when loop 1 is NOT commented.
arr2: [3, 4, 2, 5, 1]
Registry: {3: 0, 4: 1, 2: 2, 5: 3, 1: 4}
sorted_arr: [5, 4, 3, 2, 1]
For iteration i = 0
True
[5, 4, 2, 3, 1]
For iteration i = 1
false
[5, 4, 2, 3, 1]
For iteration i = 2
True
[2, 4, 3, 3, 1]
For iteration i = 3
True
[2, 4, 3, 2, 1]
######Result######
[1, 2, 3, 4, 5]
4
[2, 4, 3, 2, 1]
3
The error is in your second loop, where you have:
registry[sorted_arr[i]],registry[arr[i]]= i, index
This should be:
registry[sorted_arr[i]],registry[arr2[i]]= i, index
Generally, it is a bad idea to work with such arr and arr2 variables. Instead make two functions, and pass arr as argument to the function call. The function should then make a local copy of that array ( [:]) before mutating it. All other variables should be local to the function. That way the two algorithms use their own variable scope and there is no risk of "leaking" accidently a wrong variable into the other algorithm.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I have an array a that I want to store every 5 values of in a dictionary, while programmatically creating keys.
For example:
if we have
a=[1,2,3,4,5,6,7,8,9,10]
I want the dictionary to look like this:
d={"first_title":[1,2,3,4,5], "second_title":[6,7,8,9,10]}
Edit: I have thousands of terms so I want to do this in a loop
Dictionary values can be any object, including arrays. So, you just start with an empty dict, and add array values to it.
my_dict = {}
year = 1984
for index in range(0, len(a), 5):
my_dict[year] = a[index: index+5]
year += 1
How about this?
Input:
a = [1,2,3,4,5,6,7,8,9,10]
keys = [1984, 1985, 1986, 1987]
n = 5
Code:
my_dict = {}
for i in range(len(a)//n):
key = str(keys[i]) if i < len(keys) else "after " + str(keys[-1])
my_dict[key] = a[i*n: (i+1)*n]
print(my_dict)
Output:
{'1984': [1, 2, 3, 4, 5], '1985': [6, 7, 8, 9, 10]}
Depending on your use case you could also do something like this:
# Input
a = range(22)
keys = [1984, 1985, 1986] # maybe replace it with range(1984, 2000)
n = 5
# Code
b = a
my_dict = {}
for i in range(min(len(keys), len(a)//n)):
key = keys[min(i, len(keys)-1)]
my_dict[key] = b[:n]
b = b[n:]
my_dict['later'] = b
print(my_dict)
# Output
{
1984: [0, 1, 2, 3, 4],
1985: [5, 6, 7, 8, 9],
1986: [10, 11, 12, 13, 14],
'later': [15, 16, 17, 18, 19, 20, 21]
}
A somewhat general and pythonic solution is the following:
from itertools import izip_longest
def grouper(n, iterable, fillvalue=None):
"""grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"""
args = [iter(iterable)] * n
return izip_longest(fillvalue=fillvalue, *args)
keys = ["first-title", "second-title"]
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
result = {key: list(group) for key, group in zip(keys, grouper(5, a))}
This uses the grouper recipe (see this answer for a better explanation). A less pythonic solution, is to iterate over the pair of keys and groups using a for loop:
result = {}
for key, group in zip(keys, grouper(5, a)):
result[key] = group
In both cases the output is:
{'first-title': [1, 2, 3, 4, 5], 'second-title': [6, 7, 8, 9, 10]}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I have an array of integers say:
arr = [1,2,3,4,5,6,7,8,9,10]
And two other arrays that define how I should reorder it:
A = [1,4,5,7,8]
B = [1,3,4,5,6]
A and B have the same size.
I would like to reorder arr in a way that the values in A come before the values in B, but the values that don't show up in either arrays stay in the same place. For example:
>>> reorder(arr, A, B)
[1, 2, 4, 5, 7, 8, 3, 6, 9, 10]
>>> C = iter(A + [b for b in B if b not in A])
>>> [next(C) if e in A+B else e for e in arr]
[1, 2, 4, 5, 7, 8, 3, 6, 9, 10]
Make a comparison function, and then you can use the usual sorted function.
from functools import cmp_to_key
arr = [1,2,3,4,5,6,7,8,9,10]
A = [1,4,5,7,8]
B = [1,3,4,5,6]
def cmp(x, y):
if x == y:
return 0
index_x = arr.index(x)
index_y = arr.index(y)
if x in A and y in A:
# keep the initial order between x and y
return index_x - index_y
if x in A and y in B:
# x first
return -1
if x in B and y in A:
# y first
return 1
# keep the initial order between x and y
return index_x - index_y
print(sorted(arr, key=cmp_to_key(cmp)))
# [1, 2, 4, 5, 7, 8, 3, 6, 9, 10]
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I'm looking for an effective way to group a list of integers into a list of lists, where the sum of the original items doesn't exceed a given number.
Please consider this list of integers:
[1, 1, 1, 1, 2, 2, 1, 3, 1, 1, 2]
Which should be grouped so that the sum of the items never exceeds 3:
[[1, 1, 1], [1, 2], [2, 1], [3], [1, 1], [2]]
def group(lst, limit):
lim = 0
grp = []
for x in lst:
if x + lim > limit:
yield grp
grp = []
lim = 0
grp.append(x)
lim += x
yield grp
print list(group([1, 1, 1, 1, 2, 2, 1, 3, 1, 1, 2], 3))
Using itertools.groupby:
import itertools
def sumkey(n):
sc = [0, 0] # sum, count => group by
def keyfunc(x):
sc[0] += x
if sc[0] > n:
sc[1] += 1
sc[0] = x
return sc[1]
return keyfunc
xs = [1, 1, 1, 1, 2, 2, 1, 3, 1, 1, 2]
print([list(grp) for _, grp in itertools.groupby(xs, key=sumkey(3))])
In Python 3, sumkey could be written as following using nonlocal:
def sumkey(n):
sum_, count = 0, 0
def keyfunc(x):
nonlocal sum_, count
sum_ += x
if sum_ > n:
count += 1
sum_ = x
return count
return keyfunc
Not the most clever solution, but clean and simple enough:
def makeList(inList, n):
aList = []
while len(inList) > 0 and sum(aList) + inList[0] <= n :
aList.append(inList.pop(0))
return aList
def groupLists(inList, n, outList = []):
if not n:
raise ValueError("Please enter a positive integer")
while len(inList):
outList.append(makeList(inList, n))
return outList
print groupLists([1,1,1,1,2,2,1,3,1,1,2], 3)