Combination of betting odds in Python - python

So I'm new to Python and I've decided to work on a project that I'm interested in. I've connected to an API to get betting odds from different bookies. I've successfully got the data and stored in a Sqlite3 database. The next step is to compare the odds, and this is where I'm getting stuck.
So let's say I have a list of odds from 3 bookies:
bookie1 = [1,2]
bookie2 = [3,4]
bookie3 = [5,6]
then I have the odds from all bookies in 1 list, such as:
bookies_all = [ [1,2], [3,4], [5,6] ]
How do I get the combinations of odds from the 3 bookies?
I expect the output to look something like this:
combos = [[1,3], [1,5], [1,4], [1,6], [2,3], [2,5], [2,4], [2,6], [3,5], [3,6],[4,5], [4,6]]
Is the best option to loop through the list?

I've coded this up and it gives me all the combinations I need.
bookies_all = [[1, 2], [3, 4], [5, 6]]
combos = []
count = 0
for outer in bookies_all:
for inner in bookies_all:
temp_list = [outer[0], inner[1]]
count += 1
combos.append(temp_list)
print(combos)
Output: [[1, 2], [1, 4], [1, 6], [3, 2], [3, 4], [3, 6], [5, 2], [5, 4], [5, 6]]
The combinations in bold are the ones I want. This code works for this example.
I will test it out for scenarios where the bookies_all list has more values.

You can use itertools.combinations to find the combinations of bookies, then use a list comprehension to interleave the items:
from itertools import combinations
bookies_all = [[1, 2], [3, 4], [5, 6]]
all_comb = list(combinations(bookies_all, 2))
#print(all_comb)
combos = [[i, j] for c in all_comb for i in c[0] for j in c[1]]
print(combos)
Output:
[[1, 3], [1, 4], [2, 3], [2, 4], [1, 5], [1, 6], [2, 5], [2, 6], [3, 5], [3, 6], [4, 5], [4, 6]]

Related

How to iterate two lists with different length together? [duplicate]

This question already has answers here:
Is there a zip-like function that pads to longest length?
(8 answers)
Closed 1 year ago.
I got two lists as shown below:
a = [[[1,2], [3, 4], [5,6]], [[8,9],[10,11]]]
b = [[[1,2], [1,3],[2,3],[3, 4],[4,6],[5,6]],[[8,9],[9,10],[10,11]]]
The values in both lists are a group of list of coordinate points. And you can notice that some of the coordinate points in list a are also shown in list b
My goal is to slice list b from the given coordinate points from list a and then append in a new list. Here is an example of what I expect to get.
Example
The first item of list a is [[1,2], [3, 4], [5,6]] which I named as a[0] while that of list b is [[1,2], [1,3],[2,3],[3, 4],[4,6],[5,6]] which I named as b[0]. Therefore, a[0] is a set of b[0]
I want to slice b[0] based on the values in a[0] into a new list which looks like [[[1,2],[1,3],[2,3],[3,4]],[[3, 4],[4,6],[5,6]]]. In other words, a[0] serves as the slicing index of b[0].
Below is my code, and I do not have any idea to execute the above statement.
for items in a:
c.append([])
for i,j in zip(range(len(items)),range(len(b))):
if i < len(items)-1:
L_i = b[j][b[j].index(a[i]):b[j].index(a[i+1])+1]
L_i = list(tuple(item) for item in L_i)
elif i == len(concave_points)-1:
temp1 = b[j][b[j].index(a[i]):]
temp2 =b[j][0:b[j].index(a[0])+1]
L_i = temp1 + temp2
L_i = list(tuple(item) for item in L_i)
And an error ValueError: [[1, 2], [3, 4], [5, 6]] is not in list is occured.
Thanks a lot.
You can zip the lists instead of their length and just slice the sublists by index
a = [[[1, 2], [3, 4], [5, 6]], [[8, 9], [10, 11]]]
b = [[[1, 2], [1, 3], [2, 3], [3, 4], [4, 6], [5, 6]], [[8, 9], [9, 10], [10, 11]]]
c = []
for aa, bb in zip(a, b):
for i in range(len(aa) - 1):
c.append(bb[bb.index(aa[i]):bb.index(aa[i + 1]) + 1])
print(c) # [[[1, 2], [1, 3], [2, 3], [3, 4]], [[3, 4], [4, 6], [5, 6]], [[8, 9], [9, 10], [10, 11]]]
And as on liner with list comprehensions
c = [bb[bb.index(aa[i]):bb.index(aa[i + 1]) + 1] for aa, bb in zip(a, b) for i in range(len(aa) - 1)]
a = [[1, 2], [3, 4], [5, 6]]
b = [[1, 2], [1, 3], [2, 3], [3, 4], [4, 6], [5, 6]]
union_a_b = []
a.extend(b)
for pair in a:
if pair not in union_a_b:
union_a_b.append(pair)
else:
continue
print(union_a_b)

Join two lists into one row-wise

I have two lists and need to join them by rows. The output looks like list3 (below). Actually there aren't any commas between the bracketed pairs. I've tried a few different things and can't figure this out.
list1 = [1, 2, 3]
list2 = [4, 5, 6]
my desired output is: list3 = [[1 4], [2 5], [3 6]]
Use zip
[[i, j] for i,j in zip(list1 , list1 )]
[[1, 4], [2, 5], [3, 6]]
I am not sure if you want the final list to be list of lists or not but I will assume you do,
list1 = [1, 2, 3]
list2 = [4, 5, 6]
res = [[*np.asarray([list1, list2])[:,i]] for i in range(3)]
res = [[1, 4], [2, 5], [3, 6]]

Removing duplicates from a 4D list

I'm working with a 4D list and I'm trying to remove some duplicate inner lists, I have done something, but it's not exactly working, here is my code.
mylist = [[[], [[4, 3], [4, 3]], [[3, 2], [2, 3], [3, 4]]], [[[4, 2], [2, 3]], [[4, 3], [4, 3]], [[3, 2], [2, 3], [3, 4]]]]
final_list = []
for i in mylist:
current = []
for j in i:
for k in j:
for l in zip(k, k[1:]):
if list(l) not in current:
current.append(list(l))
final_list.append(current)
print(final_list)
final_list = [[[3, 2], [2, 3], [3, 4]], [[3, 2], [2, 3], [3, 4]]]
So instead of removing elements I append the values that are the same. This should be my desired output
#Here I remove the duplicate [4,3] #And here
! !
v v
final_list = [[[], [[4, 3]], [[3, 2], [2, 3], [3, 4]]], [[[4, 2], [2, 3]], [[4, 3]], [[3, 2], [2, 3], [3, 4]]]]
I think there should be an easy way, too many nested for loops, so any help would be appreciated, thank you so much!
You can try this with itertools.groupby:
import itertools
final_list=[[list(sbls for sbls,_ in itertools.groupby(sbls)) for sbls in ls] for ls in mylist]
Same as:
final_list=[[[sbls[i] for i in range(len(sbls)) if i == 0 or sbls[i] != sbls[i-1]] for sbls in ls] for ls in mylist]
Both outputs:
final_list
[[[], [[4, 3]], [[3, 2], [2, 3], [3, 4]]],
[[[4, 2], [2, 3]], [[4, 3]], [[3, 2], [2, 3], [3, 4]]]]
It can be done manually as well, with for loops, similar to your original approach:
flist=[]
for ls in mylist:
new_ls=[]
for sbls in ls:
new_sbls = []
for elem in sbls:
if elem not in new_sbls:
new_sbls.append(elem)
new_ls.append(new_sbls)
flist.append(new_ls)
You could use itertools.chain twice in order to reduce your list to a two-dimensional list. Now you can search for duplicates (e.g. by using count to count the numbers of occurrences. There are many solutions for this). Once you found all your duplicate entries, iterate over your original list and remove all but one occurrence of the duplicates:
import itertools
flat_list = itertools.chain(*itertools.chain(*mylist))
# TODO find duplicates in flat list
duplicates = ...
# TODO remove all duplicates from the original list

cannot understand the ouput of this for() function

transposed = []
matrix = [[1,2,3,4],[4,5,6,7]]
for i in range(len(matrix[0])):
transpose_row = []
for row in matrix:
transpose_row.append(row[i])
transposed.append(transpose_row)
the output is [[1, 4], [1, 4], [2, 5], [2, 5], [3, 6], [3, 6], [4, 7], [4, 7]].
but in the second for 1 is firstly added in the transpose_row, and then 4 is added too, which means, that [1] is at the first time added and [1, 4] at the second time added to the list transposed. So the output confuses me.

Remove sublist after first element appears n times [closed]

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 a long nested list. Each sublist contains 2 elements. What I would like to do is iterate over the full list and remove sublists once I've found the first element more than 3 times.
Example:
ls = [[1,1], [1,2], [1,3], [1,4], [2,2], [2,3], [3,4], [3,5], [3,6], [3,7]]
desired_result = [[1,1], [1,2], [1,3], [2,2], [2,3], [3,4], [3,5], [3,6]]
If the input is sorted by the first element, you could use groupby and islice:
from itertools import groupby, islice
from operator import itemgetter
ls = [[1, 1], [1, 2], [1, 3], [1, 4], [2, 2], [2, 3], [3, 4], [3, 5], [3, 6], [3, 7]]
result = [e for _, group in groupby(ls, key=itemgetter(0)) for e in islice(group, 3)]
print(result)
Output
[[1, 1], [1, 2], [1, 3], [2, 2], [2, 3], [3, 4], [3, 5], [3, 6]]
The idea is to group the elements by the first value using groupby, and then fetch the first 3 values, if they exist, using islice.
You can do it like below:
ls = [[1,1], [1,2], [1,3], [1,4], [2,2], [2,3], [3,4], [3,5], [3,6], [3,7]]
val_count = dict.fromkeys(set([i[0] for i in ls]), 0)
new_ls = []
for i in ls:
if val_count[i[0]] < 3:
val_count[i[0]] += 1
new_ls.append(i)
print(new_ls)
Output:
[[1, 1], [1, 2], [1, 3], [2, 2], [2, 3], [3, 4], [3, 5], [3, 6]]
Probably not the shortest answer.
The idea is to count occurrences while you're iterating over ls
from collections import defaultdict
filtered_ls = []
counter = defaultdict(int)
for l in ls:
counter[l[0]] += 1
if counter[l[0]] > 3:
continue
filtered_ls += [l]
print(filtered_ls)
# [[1, 1], [1, 2], [1, 3], [2, 2], [2, 3], [3, 4], [3, 5], [3, 6]]
You can use collections.defaultdict to aggregate by first value in O(n) time. Then use itertools.chain to construct a list of lists.
from collections import defaultdict
from itertools import chain
dd = defaultdict(list)
for key, val in ls:
if len(dd[key]) < 3:
dd[key].append([key, val])
res = list(chain.from_iterable(dd.values()))
print(res)
# [[1, 1], [1, 2], [1, 3], [2, 2], [2, 3], [3, 4], [3, 5], [3, 6]]
Ghillas BELHADJ answer is good. But you should consider defaultdict for this task. The idea is taken from Raymond Hettinger who suggested to use defaultdict for grouping and counting tasks
from collections import defaultdict
def remove_sub_lists(a_list, nth_occurence):
found = defaultdict(int)
for sublist in a_list:
first_index = sublist[0]
print(first_index)
found[first_index] += 1
if found[first_index] <= nth_occurence:
yield sublist
max_3_times_first_index = list(remove_sub_lists(ls, 3)))
If the list is already sorted, you can use itertools.groupby then just keep the first three items from each group
>>> import itertools
>>> ls = [[1,1], [1,2], [1,3], [1,4], [2,2], [2,3], [3,4], [3,5], [3,6], [3,7]]
>>> list(itertools.chain.from_iterable(list(g)[:3] for _,g in itertools.groupby(ls, key=lambda i: i[0])))
[[1, 1], [1, 2], [1, 3], [2, 2], [2, 3], [3, 4], [3, 5], [3, 6]]
Here's an option that doesn't use any modules:
countDict = {}
for i in ls:
if str(i[0]) not in countDict.keys():
countDict[str(i[0])] = 1
else:
countDict[str(i[0])] += 1
if countDict[str(i[0])] > 3:
ls.remove(i)

Categories