How to interchange an element within multidimensional list in python? - python

I'm unable to change the elements of a multidimensional list. The code does work on a simple list, but not on a lists within a list. I assume there is a correct way of modifying a multidimensional list?
The code I'm stuck with:
curpos = [[88, 118, 1], [200, 118, 0], [312, 118, 2],
[88, 230, 3], [200, 230, 4], [312, 230, 5],
[88, 342, 6], [200, 342, 7], [312, 342, 8]]
movls = ['right', 'down', 'left']
def move_tile(current_loc, movlist):
result = []
temp = current_loc.copy()
for i in temp:
if i[2] == 0:
empty = temp.index(i)
for j in movlist:
if j == 'right':
temp[empty][2] = temp[empty+1][2] # the problem is here, it changes the origin current_loc instead of the copy temp
temp[empty+1][2] = 0
elif j == 'down':
temp[empty][2] = temp[empty+3][2]
temp[empty+3][2] = 0
elif j == 'left':
temp[empty][2] = temp[empty-1][2]
temp[empty-1][2] = 0
elif j == 'up':
temp[empty][2] = temp[empty-3][2]
temp[empty-3][2] = 0
print(temp) # this outputs [[88, 118, 1], [200, 118, 2], [312, 118, 0], [88, 230, 3], [200, 230, 4], [312, 230, 5], [88, 342, 6], [200, 342, 7], [312, 342, 8]]
result.append(temp) # but this appends [88, 118, 0], [200, 118, 1], [312, 118, 0], [88, 230, 3], [200, 230, 0], [312, 230, 5], [88, 342, 6], [200, 342, 7], [312, 342, 8]
temp = current_loc.copy() # does not reset the temporary var
return result
print(move_tile(curpos, movls))
The correct output (without the print(temp) should be something like this:
[[[88, 118, 1], [200, 118, 2], [312, 118, 0],
[88, 230, 3], [200, 230, 4], [312, 230, 5],
[88, 342, 6], [200, 342, 7], [312, 342, 8]],
[[88, 118, 1], [200, 118, 4], [312, 118, 2],
[88, 230, 3], [200, 230, 0], [312, 230, 5],
[88, 342, 6], [200, 342, 7], [312, 342, 8]],
[[88, 118, 0], [200, 118, 1], [312, 118, 2],
[88, 230, 3], [200, 230, 4], [312, 230, 5],
[88, 342, 6], [200, 342, 7], [312, 342, 8]]]

You can use deepcopy to ensure that temp is a separate list. Making this change will generate the output that you have described above.
from copy import deepcopy
curpos = [[88, 118, 1], [200, 118, 0], [312, 118, 2],
[88, 230, 3], [200, 230, 4], [312, 230, 5],
[88, 342, 6], [200, 342, 7], [312, 342, 8]]
movls = ['right', 'down', 'left']
def move_tile(current_loc, movlist):
result = []
temp = deepcopy(current_loc)
for i in temp:
if i[2] == 0:
empty = temp.index(i)
for j in movlist:
if j == 'right':
temp[empty][2] = temp[empty+1][2]
temp[empty+1][2] = 0
elif j == 'down':
temp[empty][2] = temp[empty+3][2]
temp[empty+3][2] = 0
elif j == 'left':
temp[empty][2] = temp[empty-1][2]
temp[empty-1][2] = 0
elif j == 'up':
temp[empty][2] = temp[empty-3][2]
temp[empty-3][2] = 0
result.append(temp)
temp = deepcopy(current_loc)
return result
print(move_tile(curpos, movls))

Related

Convert Bytes into BufferedReader object in Python?

The title of this question is the same as this one, and I have voted to reopoen the question.
I want to convert a byte object into a BufferedReader one, and here is my attempts(after referring to many articles):
import numpy as np
from PIL import Image as PILImage
from io import BytesIO
img_np = np.asarray([[[16, 16, 16], [2, 2, 2], [0, 0, 0], [6, 6, 6], [8, 8, 8], [0, 0, 0], [21, 21, 21], [3, 3, 3], [0, 0, 0], [62, 62, 62]], [[0, 0, 0], [71, 71, 71], [142, 142, 142], [107, 107, 107], [99, 99, 99], [101, 101, 101], [4, 4, 4], [86, 86, 86], [99, 99, 99], [146, 146, 146]], [[162, 162, 162], [203, 203, 203], [192, 192, 192], [228, 228, 228], [191, 191, 191], [178, 178, 178], [222, 222, 222], [200, 200, 200], [198, 198, 198], [182, 182, 182]], [[117, 117, 117], [178, 178, 178], [199, 199, 199], [214, 214, 214], [222, 222, 222], [208, 208, 208], [255, 255, 255], [251, 251, 251], [219, 219, 219], [255, 255, 255]], [[0, 0, 0], [0, 0, 0], [80, 80, 80], [169, 169, 169], [193, 193, 193], [238, 238, 238], [239, 239, 239], [243, 243, 243], [254, 254, 254], [230, 230, 230]], [[20, 20, 20], [20, 20, 20], [9, 9, 9], [1, 1, 1], [130, 130, 130], [194, 194, 194], [216, 216, 216], [255, 255, 255], [252, 252, 252], [255, 255, 255]], [[9, 9, 9], [0, 0, 0], [0, 0, 0], [0, 0, 0], [3, 3, 3], [44, 44, 44], [191, 191, 191], [217, 217, 217], [248, 248, 248], [225, 225, 225]], [[0, 0, 0], [11, 11, 11], [3, 3, 3], [11, 11, 11], [6, 6, 6], [15, 15, 15], [0, 0, 0], [153, 153, 153], [255, 255, 255], [253, 253, 253]], [[0, 0, 0], [5, 5, 5], [1, 1, 1], [4, 4, 4], [8, 8, 8], [4, 4, 4], [3, 3, 3], [0, 0, 0], [159, 159, 159], [241, 241, 241]], [[10, 10, 10], [9, 9, 9], [6, 6, 6], [2, 2, 2], [0, 0, 0], [0, 0, 0], [3, 3, 3], [20, 20, 20], [0, 0, 0], [185, 185, 185]]])
im = PILImage.fromarray(img_np.astype(np.uint8))
# im.save('./temp.jpeg', "JPEG")
# f = open('./temp.jpeg', 'rb')
# print(type(f))
#
b_handle = io.BytesIO()
im.save(b_handle, format="JPEG")
# b = im.tobytes()
print(type(b_handle))
b = b_handle.read()
print(type(b))
print(b)
im.save(b_handle, format="JPEG")
b_br = io.BufferedReader(b_handle)
print(type(b_br))
b = b_br.read()
print(type(b))
print(b)
The output is as below:
<class '_io.BytesIO'>
<class 'bytes'>
b''
<class '_io.BufferedReader'>
<class 'bytes'>
b''
It seems that the file like objects are empty. I know that for the b_handle I can get the value by b_handle.getvalue() but for the bufferedreader it doesn't work as a file object.
How can I convert a byte string into a bufferedreader object, the same as I open a file?
You are almost there. Once you save the image bytes into the buffer you need to seek(Change stream position) to byte offset 0 prior to the read call.
b_handle = io.BytesIO()
im.save(b_handle, format="JPEG")
b_handle.seek(0)
b_handle.name = "temp.jpeg"
b_br = io.BufferedReader(b_handle)
b = b_br.read()
Example,
>>> from io import BytesIO, BufferedReader
>>>
>>> b_handle = BytesIO()
>>> b_handle.write(b"Hello World")
11
>>> b_handle.seek(0) # This is important.
0
>>> br = BufferedReader(b_handle)
>>> br
<_io.BufferedReader>
>>> br.read()
b'Hello World'

How can I concatenate a list of 2D numpy arrays?

I have a list of nested numpy arrays of shape (30,3). I tried to use numpy's vstack, hstack and concatenate, but I get an error: ValueError: all the input array dimensions except for the concatenation axis must match exactly
`[array([[[430, 110, 10],
[ 62, 167, 10],
[116, 136, 10],
[341, 104, 10],
[ 21, 116, 10],
[371, 20, 10],
[343, 197, 10],
[ 59, 308, 10],
[ 33, 23, 10],
[215, 70, 10],
[256, 73, 10],
[ 94, 397, 10],
[135, 251, 10],
[202, 283, 10],
[233, 313, 10],
[319, 13, 10],
[ 98, 273, 10],
[261, 167, 10],
[160, 296, 9],
[137, 56, 10],
[ 21, 320, 10],
[ 77, 109, 9],
[295, 356, 10],
[178, 425, 10],
[259, 35, 9],
[319, 416, 9],
[386, 331, 9],
[319, 43, 9],
[209, 409, 9],
[115, 199, 9]]], dtype=uint16),` etc
I would like it to transform this into a normal list of lists, so getting rid of the array signs, just a plain list that I can easily manipulate.
If you want a plain list without the array signs, use <your_array>.tolist() The .tolist() will convert it to a plain list which is easily manipulatable. I hope this helps you

Large amount of lists concatenation [duplicate]

This question already has answers here:
Merge lists that share common elements
(15 answers)
Closed 4 years ago.
I'm trying to make a function which concatenate multiple list if one element is the same in 2 or more different list.
Example :
[[1,2],[3,4,5],[0,4]] would become [[1,2],[0,3,4,5]
[[1],[1,2],[0,2]] would become [[0,1,2]]
[[1, 2], [2, 3], [3, 4]] would become [[1,2,3,4]]
In fact we just regroup the list if they have a common element and we delete one of the two element. The finals lists must have unique elements.
I tried to make the following function. It works, but when using big list (around 100 or 200 lists of list), I got the following recursion error :
RecursionError: maximum recursion depth exceeded while getting the repr of an object
def concat(L):
break_cond = False
print(L)
for L1 in L:
for L2 in L:
if (bool(set(L1) & set(L2)) and L1 != L2):
break_cond = True
if (break_cond):
i, j = 0, 0
while i < len(L):
while j < len(L):
if (bool(set(L[i]) & set(L[j])) and i != j):
L[i] = sorted(L[i] + list(set(L[j]) - set(L[i])))
L.pop(j)
j += 1
i += 1
return concat(L)
Moreover, I would like to do it using only basic python and not that much library. Any idea ? Thanks
Example of list where I get the error :
[[0, 64], [1, 120, 172], [2, 130], [3, 81, 102], [5, 126], [6, 176], [7, 21, 94], [8, 111, 167], [9, 53, 60, 138], [10, 102, 179], [11, 45, 72], [12, 53, 129], [14, 35, 40, 58, 188], [15, 86], [18, 70, 94], [19, 28], [20, 152], [21, 24], [22, 143, 154], [23, 110, 171], [24, 102, 144], [25, 73, 106, 187], [26, 189], [28, 114, 137], [29, 148], [30, 39], [31, 159], [33, 44, 132, 139], [34, 81, 100, 136, 185], [35, 53], [37, 61, 138], [38, 144, 147, 165], [41, 42, 174], [42, 74, 107, 162], [43, 99, 123], [44, 71, 122, 126], [45, 74, 144], [47, 94, 151], [48, 114, 133], [49, 130, 144], [50, 51], [51, 187], [52, 124, 142, 146, 167, 184], [54, 97], [55, 94], [56, 88, 128, 166], [57, 63, 80], [59, 89], [60, 106, 134, 142], [61, 128, 145], [62, 70], [63, 73, 76, 101, 106], [64, 80, 176], [65, 187, 198], [66, 111, 131, 150], [67, 97, 128, 159], [68, 85, 128], [69, 85, 169], [70, 182], [71, 123], [72, 85, 94], [73, 112, 161], [74, 93, 124, 151, 191], [75, 163], [76, 99, 106, 129, 138, 152, 179], [77, 89, 92], [78, 146, 156], [79, 182], [82, 87, 130, 179], [83, 148], [84, 110, 146], [85, 98, 137, 177], [86, 198], [87, 101], [88, 134, 149], [89, 99, 107, 130, 193], [93, 147], [95, 193], [96, 98, 109], [104, 105], [106, 115, 154, 167, 190], [107, 185, 193], [111, 144, 153], [112, 128, 188], [114, 136], [115, 146], [118, 195], [119, 152], [121, 182], [124, 129, 177], [125, 156], [126, 194], [127, 198], [128, 149], [129, 153], [130, 164, 196], [132, 140], [133, 181], [135, 165, 170, 171], [136, 145], [141, 162], [142, 170, 187], [147, 171], [148, 173], [150, 180], [153, 191], [154, 196], [156, 165], [157, 177], [158, 159], [159, 172], [161, 166], [162, 192], [164, 184, 197], [172, 199], [186, 197], [187, 192]]
As mentioned by #ScottBoston this is a graph problem, known as connected components, I suggest you used networkx as indicated by #ScottBoston, in case you cannot here is a version without networkx:
from itertools import combinations
def bfs(graph, start):
visited, queue = set(), [start]
while queue:
vertex = queue.pop(0)
if vertex not in visited:
visited.add(vertex)
queue.extend(graph[vertex] - visited)
return visited
def connected_components(G):
seen = set()
for v in G:
if v not in seen:
c = set(bfs(G, v))
yield c
seen.update(c)
def graph(edge_list):
result = {}
for source, target in edge_list:
result.setdefault(source, set()).add(target)
result.setdefault(target, set()).add(source)
return result
def concat(l):
edges = []
s = list(map(set, l))
for i, j in combinations(range(len(s)), r=2):
if s[i].intersection(s[j]):
edges.append((i, j))
G = graph(edges)
result = []
unassigned = list(range(len(s)))
for component in connected_components(G):
union = set().union(*(s[i] for i in component))
result.append(sorted(union))
unassigned = [i for i in unassigned if i not in component]
result.extend(map(sorted, (s[i] for i in unassigned)))
return result
print(concat([[1, 2], [3, 4, 5], [0, 4]]))
print(concat([[1], [1, 2], [0, 2]]))
print(concat([[1, 2], [2, 3], [3, 4]]))
Output
[[0, 3, 4, 5], [1, 2]]
[[0, 1, 2]]
[[1, 2, 3, 4]]
You can use networkx library because is a graph theory and connected components problem:
import networkx as nx
l = [[1,2],[3,4,5],[0,4]]
#l = [[1],[1,2],[0,2]]
#l = [[1, 2], [2, 3], [3, 4]]
G = nx.Graph()
#Add nodes to Graph
G.add_nodes_from(sum(l, []))
#Create edges from list of nodes
q = [[(s[i],s[i+1]) for i in range(len(s)-1)] for s in l]
for i in q:
#Add edges to Graph
G.add_edges_from(i)
#Find all connnected components in graph and list nodes for each component
[list(i) for i in nx.connected_components(G)]
Output:
[[1, 2], [0, 3, 4, 5]]
Output if uncomment line 2 and comment line 1:
[[0, 1, 2]]
Likewise for line 3:
[[1, 2, 3, 4]]
Here's an iterative approach, should be about as efficient as you can probably get in pure python. One thing is having to spend an extra pass removing duplicates at the end.
original_list = [[1,2],[3,4,5],[0,4]]
mapping = {}
rev_mapping = {}
for i, candidate in enumerate(original_list):
sentinel = -1
for item in candidate:
if mapping.get(item, -1) != -1:
merge_pos = mapping[item]
#update previous list with all new candidates
for item in candidate:
mapping[item] = merge_pos
rev_mapping[merge_pos].extend(candidate)
break
else:
for item in candidate:
mapping[item] = i
rev_mapping.setdefault(i, []).extend(candidate)
result = [list(set(item)) for item in rev_mapping.values()]
print(result)
Output:
[[1, 2], [0, 3, 4, 5]]
You can use a recursive version of the breadth-first search with no imports:
def group_vals(d, current, _groups, _seen, _master_seen):
if not any(set(current)&set(i) for i in d if i not in _seen):
yield list({i for b in _groups for i in b})
for i in d:
if i not in _master_seen:
yield from group_vals(d, i, [i], [i], _master_seen+[i])
else:
for i in d:
if i not in _seen and set(current)&set(i):
yield from group_vals(d, i, _groups+[i], _seen+[i], _master_seen+[i])
def join_data(_data):
_final_result = list(group_vals(_data, _data[0], [_data[0]], [_data[0]], []))
return [a for i, a in enumerate(_final_result) if a not in _final_result[:i]]
c = [[[1,2],[3,4,5],[0,4]], [[1],[1,2],[0,2]], [[1, 2], [2, 3], [3, 4]]]
print(list(map(join_data, c)))
Output:
[
[[1, 2], [0, 3, 4, 5]],
[[0, 1, 2]],
[[1, 2, 3, 4]]
]
if you want it in simple form here is solution :
def concate(l):
len_l = len(l)
i = 0
while i < (len_l - 1):
for j in range(i + 1, len_l):
# i,j iterate over all pairs of l's elements including new
# elements from merged pairs. We use len_l because len(l)
# may change as we iterate
i_set = set(l[i])
j_set = set(l[j])
if len(i_set.intersection(j_set)) > 0:
# Remove these two from list
l.pop(j)
l.pop(i)
# Merge them and append to the orig. list
ij_union = list(i_set.union(j_set))
l.append(ij_union)
# len(l) has changed
len_l -= 1
# adjust 'i' because elements shifted
i -= 1
# abort inner loop, continue with next l[i]
break
i += 1
return l
If you want to see how the algorithm works, you can use this script which uses the connectivity matrix:
import numpy
def Concatenate(L):
result = []
Ls_length = len(L)
conn_mat = numpy.zeros( [Ls_length, Ls_length] ) # you can use a list of lists instead of a numpy array
check_vector = numpy.zeros( Ls_length ) # you can use a list instead of a numpy array
idx1 = 0
while idx1 < Ls_length:
idx2 = idx1 + 1
conn_mat[idx1,idx1] = 1 # the diaginal is always 1 since every set intersects itself.
while idx2 < Ls_length:
if bool(set(L[idx1]) & set(L[idx2]) ): # 1 if the sets idx1 idx2 intersect, and 0 if they don't.
conn_mat[idx1,idx2] = 1 # this is clearly a symetric matrix.
conn_mat[idx2,idx1] = 1
idx2 += 1
idx1 += 1
print (conn_mat)
idx = 0
while idx < Ls_length:
if check_vector[idx] == 1: # check if we already concatenate the idx element of L.
idx += 1
continue
connected = GetAllPositiveIntersections(idx, conn_mat, Ls_length)
r = set()
for idx_ in connected:
r = r.union(set(L[idx_]))
check_vector[idx_] = 1
result.append(list(r))
return result
def GetAllPositiveIntersections(idx, conn_mat, Ls_length):
# the elements that intersect idx are coded with 1s in the ids' row (or column, since it's a symetric matrix) of conn_mat.
connected = [idx]
i = 0
idx_ = idx
while i < len(connected):
j = 0
while j < Ls_length:
if bool(conn_mat[idx_][j]):
if j not in connected: connected.append(j)
j += 1
i += 1
if i < len(connected): idx_ = connected[i]
return list(set(connected))
Then you just:
L = [[1,2],[3,4,5],[0,4]]
r = Concatenate(L)
print(r)

script is changing the value of a variable for no reason [duplicate]

This question already has answers here:
How do I clone a list so that it doesn't change unexpectedly after assignment?
(24 answers)
Closed 4 years ago.
When running this specific block of my script, record[r] is changing its value. Here're some lines I get printed out:
record[r] [[70, 190, 526, 9], [100, 160, 354, 60], [61, 45, 276, 15], [45, 61, 454, 28], [254, 192, 15, 20]] r : 0
[[190, 70, 524, 15], [160, 100, 353, 60], [45, 61, 280, 15], [45, 61, 456, 25], [245, 186, 14, 24]]
record[r] [[190, 70, 524, 15], [160, 100, 353, 60], [45, 61, 280, 15], [45, 61, 456, 25], [245, 186, 14, 24]] r : 0
[[190, 70, 528, 18], [100, 160, 355, 69], [45, 61, 277, 17], [45, 61, 454, 23], [233, 184, 9, 27]]
record[r] [[190, 70, 528, 18], [100, 160, 355, 69], [45, 61, 277, 17], [45, 61, 454, 23], [233, 184, 9, 27]] r : 0
[[190, 70, 526, 16], [160, 100, 354, 66], [45, 61, 277, 11], [61, 45, 450, 17], [242, 181, 6, 37]]
record[r] [[190, 70, 526, 16], [160, 100, 354, 66], [45, 61, 277, 11], [61, 45, 450, 17], [242, 181, 6, 37]] r : 0
[[190, 70, 531, 8], [100, 160, 358, 72], [61, 45, 280, 8], [45, 61, 448, 7], [240, 178, 4, 28]]
record[r] [[190, 70, 531, 8], [100, 160, 358, 72], [61, 45, 280, 8], [45, 61, 448, 7], [240, 178, 4, 28]] r : 0
[[190, 70, 531, 5], [100, 160, 360, 71], [45, 61, 277, 9], [45, 61, 452, 12], [238, 175, 8, 20]]
record[r] [[190, 70, 531, 5], [100, 160, 360, 71], [45, 61, 277, 9], [45, 61, 452, 12], [238, 175, 8, 20]] r : 0
Code:
for i in range(10):
print "loop {} of 100".format(i)
for r in range(3):
boo = False
while boo == False:
print "record[r]",record[r],"r :",r
data = place2(record[r])
print(data)
if validate(data, True):
boo = True
print "GETTING PAST WHILE"
record, gen2 = measure2(data, gen2, record)
def place2(inp):
out = inp
for i in range(4):
n = randint(0,1)
if n == 1:
out[i] = flip(out[i])
out[i][2] += randint(-5,5)
out[i][3] += randint(-10,10)
out[4][2] += randint(-5,5)
out[4][3] += randint(-10,10)
out[4][1] += randint(-10,10)
out[4][0] += randint(-15,15)
return out
def validate(inp, check):
p = 0
q = 0
r = 0
s = 0
for i in range(5):
for j in range(5):
if i != j:
if inp[i][2] - inp[j][2] <= (-1 * inp[i][0] )or inp[i][2] - inp[j][2] >= inp[j][0]:
p +=1
if inp[i][3] - inp[j][3] <= (-1 * inp[i][1]) or inp[i][3] - inp[j][3] >= inp[j][1]:
q += 1
if inp[i][2] >= 0 and inp[i][2] <= 600 - inp[i][0]:
r +=1
if inp[i][3] >= 0 and inp[i][3] <= 225 - inp[i][1]:
s +=1
if check:
print(p,q,r,s)
if p == 20 and s + r == 40:
return True
else:
return False
Its also worth nothing that I never get GETTING PAST WHILE printed out so I know the culprit must be in the while loop.
record[r] should be static during the while loop and I can't explain for the life of me why it's not. I've isolated out the validate function to see if that's causing it and the problem still happens and I have no idea why the place2 function would be causing the issue.
I have spent probably 3 hours in total looking for a solution and have not found one so I'm hoping that SO can help.
When you execute place2(inp), you will assign out = inp. This is not a copy !
What you're doing is pointing out toward inp. So when you change out, you also change inp.
You should use deepcopy if you don't want to modify your inp variable.
import copy
def place2(inp):
out = copy.deepcopy(inp) # This will do a copy instead of pointing.
for i in range(4):
n = randint(0,1)
if n == 1:
out[i] = flip(out[i])
# etc.
To be clearer, here's what happens without deepcopy :
a = [1,2]
b = a
b[0] = 10
print(a) # [10,2]
with deepcopy:
a = [1,2]
b = copy.deepcopy(a)
b[0] = 10
print(a) # [1,2]

Python thread and global interpreter lock when access same object

I am trying to understand python thread and how it works.
From my understanding, I know that there is GIL(Global Interpreter Lock) to prevent two thread to access memory at the same time.
This is pretty reasonable, even though it slows down the program.
But the code below, show unexpected result.
import thread, time
mylist = [[0,1]]
def listTo300Elem(id):
while len(mylist) < 300:
mylist.append([id, mylist[-1][1]+1])
thread.start_new_thread(listTo300Elem, (1,))
thread.start_new_thread(listTo300Elem, (2,))
thread.start_new_thread(listTo300Elem, (3,))
thread.start_new_thread(listTo300Elem, (4,))
thread.start_new_thread(listTo300Elem, (5,))
thread.start_new_thread(listTo300Elem, (6,))
thread.start_new_thread(listTo300Elem, (7,))
time.sleep(5)
print mylist
print len(mylist)
And the result is
[[0, 1], [1, 2], [1, 3], [1, 4], [1, 5], [1, 6], [1, 7], [1, 8], [1, 9], [1, 10], [1, 11], [1, 12], [1, 13], [1, 14], [1, 15], [1, 16], [1, 17], [1, 18], [1, 19], [1, 20], [1, 21], [1, 22], [1, 23], [1, 24], [1, 25], [1, 26], [1, 27], [1, 28], [1, 29], [1, 30], [1, 31], [1, 32], [1, 33], [1, 34], [1, 35], [1, 36], [1, 37], [1, 38], [1, 39], [1, 40], [1, 41], [1, 42], [1, 43], [1, 44], [1, 45], [1, 46], [1, 47], [1, 48], [1, 49], [1, 50], [1, 51], [1, 52], [1, 53], [1, 54], [1, 55], [1, 56], [1, 57], [1, 58], [1, 59], [1, 60], [1, 61], [1, 62], [1, 63], [1, 64], [1, 65], [1, 66], [1, 67], [1, 68], [1, 69], [1, 70], [1, 71], [1, 72], [2, 73], [2, 74], [2, 75], [2, 76], [2, 77], [2, 78], [2, 79], [5, 80], [5, 81], [5, 82], [5, 83], [5, 84], [5, 85], [5, 86], [5, 87], [5, 88], [5, 89], [5, 90], [5, 91], [5, 92], [5, 93], [5, 94], [3, 95], [3, 96], [3, 97], [3, 98], [3, 99], [3, 100], [3, 101], [3, 102], [3, 103], [3, 104], [3, 105], [3, 106], [3, 107], [3, 108], [3, 109], [3, 110], [3, 111], [3, 112], [3, 113], [3, 114], [3, 115], [3, 116], [3, 117], [7, 118], [7, 119], [7, 120], [7, 121], [7, 122], [7, 123], [7, 124], [2, 80], [2, 81], [2, 82], [2, 83], [2, 84], [2, 85], [2, 86], [2, 87], [2, 88], [2, 89], [2, 90], [2, 91], [2, 92], [2, 93], [2, 94], [2, 95], [2, 96], [2, 97], [2, 98], [2, 99], [2, 100], [2, 101], [2, 102], [2, 103], [2, 104], [2, 105], [2, 106], [2, 107], [2, 108], [2, 109], [2, 110], [2, 111], [2, 112], [2, 113], [2, 114], [2, 115], [2, 116], [2, 117], [2, 118], [2, 119], [2, 120], [2, 121], [2, 122], [2, 123], [2, 124], [2, 125], [2, 126], [2, 127], [2, 128], [2, 129], [2, 130], [2, 131], [2, 132], [2, 133], [2, 134], [2, 135], [2, 136], [2, 137], [2, 138], [2, 139], [2, 140], [2, 141], [7, 125], [7, 126], [7, 127], [7, 128], [7, 129], [7, 130], [7, 131], [7, 132], [7, 133], [7, 134], [7, 135], [7, 136], [7, 137], [7, 138], [7, 139], [7, 140], [7, 141], [7, 142], [7, 143], [7, 144], [7, 145], [7, 146], [7, 147], [7, 148], [7, 149], [7, 150], [7, 151], [7, 152], [7, 153], [7, 154], [7, 155], [7, 156], [7, 157], [7, 158], [7, 159], [7, 160], [7, 161], [7, 162], [7, 163], [7, 164], [7, 165], [7, 166], [7, 167], [7, 168], [7, 169], [7, 170], [7, 171], [6, 172], [6, 173], [6, 174], [6, 175], [6, 176], [6, 177], [6, 178], [3, 179], [3, 180], [3, 181], [3, 182], [3, 183], [3, 184], [3, 185], [3, 186], [3, 187], [3, 188], [3, 189], [3, 190], [3, 191], [3, 192], [3, 193], [3, 194], [3, 195], [3, 196], [3, 197], [3, 198], [3, 199], [3, 200], [3, 201], [7, 202], [7, 203], [7, 204], [7, 205], [7, 206], [7, 207], [7, 208], [7, 209], [1, 210], [1, 211], [1, 212], [1, 213], [1, 214], [1, 215], [1, 216], [1, 217], [1, 218], [1, 219], [1, 220], [1, 221], [1, 222], [1, 223], [1, 224], [1, 225], [1, 226], [1, 227], [1, 228], [1, 229], [1, 230], [1, 231], [1, 232], [1, 233], [1, 234], [1, 235], [1, 236], [1, 237], [1, 238], [3, 239], [5, 240], [2, 142], [6, 179]]
304
From my understanding, the result must be in order due to GIL, but they are not.
Can I get explanation for this example and further items to study?
What did you expect? That one thread add one item, after that another thread and etc.? Than why so many threads, if they work by one at once? Threads are trying to work simultaneously with one object. But since the GIL is not a good thing to do parallel computing, they do it so ugly.
To get more undestanding how GIL works, you may add logging.
logging.basicConfig(format="%(levelname)-8s [%(asctime)s] %(threadName)-12s %(message)s", level=logging.DEBUG, filename='log.log')
def listTo300Elem(id):
list_len = len(mylist)
while list_len < 300:
item = mylist[-1][1]+1]
mylist.append([id, item])
logging.debug('Len = {}, item {} added'.format(list_len, item))
list_len = len(mylist)
logging.debug('Len = {}, exit'.format(list_len, item))
So, threading in python is not suitable for all cases.

Categories