Only first index of tuples list being used - python-3.x

im currently returning a list of Tuples using the Zip function:
The returned data is: [(13, 3), (12, 3), (11, 3), (10, 3), (9, 3), (8, 3), (6, 3), (5, 3), (4, 3)]
im looping through the data to use it but currently only the first index is being printed.
CheckPath = self.CheckQueenPathDown(QueenRowColumn,TheComparisonQueen) #This is where the list of tuples is being used
print(CheckPath) # this shows all the correct data when i print it.
for TheQueenMoves in QueenMoves:
for a,b in list(self.pieces.items()):
for CheckThePath in CheckPath:
if TheComparisonQueen == TheQueenMoves and TheComparisonQueen[0] >= 0 and TheComparisonQueen[1] <= 7 and \
TheComparisonQueen[1] >= 0 and TheComparisonQueen[0] <= 7 and CheckThePath != b: # this is the line im trying to use it in.
self.placepiece(piece, row = MoveRow, column = MoveColumn)
print(CheckThePath)
This is the code i am getting the info from:
Example data:
QueenRowColumn: (3,3)
TheComparisonQueen: (7,3)
def CheckQueenPathDown(self, QueenRowColumn, TheComparisonQueen):
row = []
column = []
CurrentLocation = QueenRowColumn
#MoveLocation = TheComparisonQueen
a = QueenRowColumn[0]
b = QueenRowColumn[1]
for i in range (-10,0):
row.append(CurrentLocation[1] - i)
column.append(a)
Down = zip(row,column)
#Down.remove(TheComparisonQueen)
return Down
im currently trying to use all the varibles of the returned data by looping through it, however only the first index appears when i print it, i dont understand what the problem is. any idea how to fix this?

zip doesn't make a list on Python 3. If you need a list, call list on the result.
On Python 3, zip returns an iterator, which is exhausted after iterating over it once. If you try to reuse it, you get no elements out of it.

Try:
def CheckQueenPathDown(self, QueenRowColumn, TheComparisonQueen):
row = []
column = []
CurrentLocation = QueenRowColumn
#MoveLocation = TheComparisonQueen
a = QueenRowColumn[0]
b = QueenRowColumn[1]
for i in range (-10,0):
row.append(CurrentLocation[1] - i)
column.append(a)
Down = zip(row,column)
#Down.remove(TheComparisonQueen)
return list(Down)
Since return list(ZIP_OBJ) will allocate memory to it so you can reuse it in the nested loop.

Related

How to use python assignment operator with multiple return values

I have a Python function which takes a parameter and returns 2 outputs. I want to call this for all the elements in a list and combine the return values for each invocation as below:
a1, b1 = func(p[0])
a2, b2 = func(p[1])
a3, b3 = func(p[3])
a = a1 & a2 & a3
b = b1 + b2 + b3
How can I refactor this to a one liner using the += , &= and the reduce operators in Python?
Thanks
Since you want a one-liner, something like this should help you:
a,b = int(all(ele == list(zip(*map(func,p)))[0][0] for ele in list(zip(*map(func,p)))[0])),sum(list(zip(*map(func,p)))[-1])
Breakdown:
The map function applies a function to an iterable.
list(map(func,p))
Prints:
[(1, 3), (2, 4), (3, 5)]
This:
list(zip([(1, 3), (2, 4), (3, 5)]))
Prints:
[((1, 3),), ((2, 4),), ((3, 5),)]
Adding an * before map would transpose the list:
list(zip(*map(func,p)))
Prints:
[(1, 2, 3), (3, 4, 5)]
The all function is combined with a simple list comprehension in order to find if all elements of sublist 1 are equal. Here is a simpler version of it:
all(ele == lst[0] for ele in lst)
The same has been applied in this case like this:
all(ele == list(zip(*map(func,p)))[0][0] for ele in list(zip(*map(func,p)))[0])
Prints:
False
In order to convert True/False to 1/0, I have used the int() function:
int(all(ele == list(zip(*map(func,p)))[0][0] for ele in list(zip(*map(func,p)))[0]))
Prints:
0
The second part of it, which is this: sum(list(zip(*map(func,p)))[-1]) calculates the sum of the second sublist.
sum(list(zip(*map(func,p)))[-1])
Prints:
12
Here is the full code:
def func(a):
return a,a+2
p = [1,2,3]
a,b = all(ele == list(zip(*map(func,p)))[0][0] for ele in list(zip(*map(func,p)))[0])),sum(list(zip(*map(func,p)))[-1])
print(a,b)
Output:
(0, 12)
We can decompose this problem into individual tasks:
Mapping a function func across the elements p[0], p[1], ... of an iterable/sequence p is map(func, p).
This already provides an iterable of (a1, b1), (a2, b2) so the assignment does not need special handling.
The chain of operations a1 & a2 & ... for a sequence/iterable a is reduce(lambda new, total: new & total) and likewise for +.
Since we have a stream of pairs of (a1, b1), ... instead of a pair of streams a1, ... and b1, ... we must operate on both at once.
The result of reducing a stream of pairs is a single pair, which we can assign to two variables as a, b = result.
from functools import reduce
def func(a): return a, a
p = range(1, 5, 2)
def reduction(new, total):
return new[0] & total[0], new[1] + total[1]
mapped = map(func, p)
reduced = reduce(reduction, mapped)
a, b = reduced
If desired, this can be written in one statement/line.
>>> a, b = reduce(lambda new, total: (new[0] & total[0], new[1] + total[1]), map(func, p))
>>> a
1
>>> b
4

Python: How to use one dictionary to use to decode the other?

Say if I had two dictionaries:
d1 = {'a':1, 'b':2}
d2 = {'a':'b', 'b':'b', 'a':'a'}
How can I use dictionary d1 as the rules to decode d2, such as:
def decode(dict_rules, dict_script):
//do something
return dict_result
decode(d1,d2)
>> {1:2, 2:2, 1:1}
of course it can be written much shorter, but here a version to see the principle:
result_list = list()
result_dict = dict()
for d2_key in d2.keys():
d2_key_decoded = d1[d2_key]
d2_value = d2[d2_key]
d2_value_decoded = d1[d2_value]
result_dict[d2_key_decoded] = d2_value_decoded
# add a tuple to the result list
result_list.append((d2_key_decoded, d2_value_decoded))
the result might be unexpected - because the resulting dict would have entries with the same key, what is not possible, so the key 1 is overwritten:
>>> # equals to :
>>> result_dict[1] = 2
>>> result_dict[2] = 2
>>> result_dict[1] = 1
>>> # Result : {1:1, 2:2}
>>> # therefore I added a list of Tuples as result :
>>> # [(1, 2), (2, 2), (1, 1)]
but as #Patrik Artner pointed out, that is not possible, because already the input dictionary can not have duplicate keys !

How to find the second most repetitive character​ ​in string using python

Here in the program how can you find the second repetitive character in the string. for ex:abcdaabdefaggcbd"​
Output : d (because 'd' occurred 3 times where 'a' occurred 4 times)​
how can I get the output, please help me.
Given below is my code:
s="abcdaabdefaggcbd"
d={}
for i in s:
d[i] = d.get(i,0)+1
print(d,"ddddd")
max2 = 0
for k,v in d.items():
if(v>max2 and v<max(d.values())):
max2=v
if max2 in d.values():
print k,"kkk"
The magnificent Python Counter and its most_common() method are very handy here.
import collections
my_string = "abcdaabdefaggcbd"
result = collections.Counter(my_string).most_common()
print(result[1])
Output
('b', 3)
In case you need to capture all the second values (if you have more than one entry) you can use the following:
import collections
my_string = "abcdaabdefaggcbd"
result = collections.Counter(my_string).most_common()
second_value = result[1][1]
seconds = []
for item in result:
if item[1] == second_value:
seconds.append(item)
print(seconds)
Output
[('b', 3), ('d', 3)]
I also wanted to add an example of solving the problem using a methodology more similar to the one that you showed in your question:
my_string="abcdaabdefaggcbd"
result={}
for character in my_string:
if character in result:
result[character] = result.get(character) + 1
else:
result[character] = 1
sorted_data = sorted([(value,key) for (key,value) in result.items()])
second_value = sorted_data[-2][0]
result = []
for item in sorted_data:
if item[0] == second_value:
result.append(item)
print(result)
Output
[(3, 'b'), (3, 'd')]
Ps
Please forgive me if I took the freedom to change variable names but I think that in this way my answer will be more readable for a broader audience.
Sort the dict's items on their values (descending) and get the second item:
>>> from collections import Counter
>>> c = Counter("abcdaabdefaggcbd")
>>> vals = sorted(c.items(), key=lambda item:item[1], reverse=True)
>>> vals
[('a', 4), ('b', 3), ('d', 3), ('c', 2), ('g', 2), ('e', 1), ('f', 1)]
>>> print(vals[1])
('b', 3)
>>>
EDIT:
or just use Counter.most_common():
>>> from collections import Counter
>>> c = Counter("abcdaabdefaggcbd")
>>> print(c.most_common()[1])
Both b and d are second most repetitive. I would think that both should be displayed. This is how I would do it:
Code:
s="abcdaabdefaggcbd"
d={}
for i in s:
ctr=s.count(i)
d[i]=ctr
fir = max(d.values())
sec = 0
for j in d.values():
if(j>sec and j<fir):
sec = j
for k,v in d.items():
if v == sec:
print(k,v)
Output:
b 3
d 3
in order to find the second most repetitive character​ ​in string you can very well use collections.Counter()
Here's an example:
import collections
s='abcdaabdefaggcbd'
count=collections.Counter(s)
print(count.most_common(2)[1])
Output: ('b', 3)
You can do a lot with Counter(). Here's a link for a further read:
More about Counter()
I hope this answers your question. Cheers!

Python dictionary keys with matching values [duplicate]

This question already has answers here:
Find all Key-Elements by the same Value in Dicts
(4 answers)
Closed 4 years ago.
I have a dictionary like this,
a= { 1:2, 3:4, 4:2, 8:3,7:4,9:3}
I want to find keys that have same values.
My output should be,
b=[ (1,4),(8,9),(3,7)]
How do I do that in a pythonic way.
a = {1:2, 3:4, 4:2, 8:3,7:4,9:3, 5: 2}
valueDict = {}
mulKeys = []
for key, value in a.items():
if valueDict.get(value) == None:
valueDict[value] = [key]
else:
preExisting = valueDict[value]
preExisting.append(key)
valueDict[value] = preExisting
nested_lst_of_tuples = [tuple(l) for l in valueDict.values()]
print(nested_lst_of_tuples)
Note that, for your given question, the output YOU mentioned is wrong.
a={ 1:2, 3:4, 4:2, 8:3,7:4,9:3}
b=set(a.values())
l=[]
for i in b:
l.append(tuple([k for k,v in a.items() if v == i]))
print l # [(1, 4), (8, 9), (3, 7)]
Distinct values in dictionary can be easily obtained using set.
tuple() converts the list into tuple.

Print the content of ResultIterable object

How can I print the content of a pyspark.resultiterable.ResultIterable object that has a list of rows and columns
Is there a built-in function for that?
I would like something like dataframe.show()
I was facing the same issue and solved it eventually, so let me share my way of doing it...
Let us assume we have two RDDs.
rdd1 = sc.parallelize([(1,'A'),(2,'B'),(3,'C')])
rdd2 = sc.parallelize([(1,'a'),(2,'b'),(3,'c')])
Let us cogroup those RDDs in order to get ResultIterable.
cogrouped = rdd1.cogroup(rdd2)
for t in cogrouped.collect():
print t
>>
(1, (<pyspark.resultiterable.ResultIterable object at 0x107c49450>, <pyspark.resultiterable.ResultIterable object at 0x107c95690>))
(2, (<pyspark.resultiterable.ResultIterable object at 0x107c95710>, <pyspark.resultiterable.ResultIterable object at 0x107c95790>))
(3, (<pyspark.resultiterable.ResultIterable object at 0x107c957d0>, <pyspark.resultiterable.ResultIterable object at 0x107c95810>))
Now we want to see what is inside of those ResultIterables.
We can do it like this:
def iterate(iterable):
r = []
for v1_iterable in iterable:
for v2 in v1_iterable:
r.append(v2)
return tuple(r)
x = cogrouped.mapValues(iterate)
for e in x.collect():
print e
or like this
def iterate2(iterable):
r = []
for x in iterable.__iter__():
for y in x.__iter__():
r.append(y)
return tuple(r)
y = cogrouped.mapValues(iterate2)
for e in y.collect():
print e
In both cases we will get the same result:
(1, ('A', 'a'))
(2, ('B', 'b'))
(3, ('C', 'c'))
Hopefully, this will help somebody in future.

Resources