cannot pickle 'generator' object created using yield key-word - python

As shown in the below posted code, I call __yieldIterables() to generate iterables according to what the list self.__itersList contains. At run time I receive the following error:
TypeError: cannot pickle 'generator' object
Please let me know how to correct the below code in such a way that I can still convert the contents of self.__itersList to iterables that can be passed to the self.run()
code:
def postTask(self):
arg0 = self.getDistancesModel().getFieldCoordinatesAsTextInWKTEPSG25832()
self.__itersList.append(self.getDistancesModel().getNZCCCenterPointsAsString())
self.__itersList.append(self.getDistancesModel().getZCCCenterPointsAsString())
self.__itersList.append(self.getDistancesModel().getNoDataCCenterPointsAsString())
with Pool(processes=self.__processesCount,initializer=self.initPool,initargs=(arg0,)) as DistancesRecordsPool.pool:
self.__iterables = self.__yieldIterables()
self.__chunkSize = PoolUtils.getChunkSizeForLenOfIterables(lenOfIterablesList=len(self.__itersList),cpuCount=self.__cpuCount)
for res in DistancesRecordsPool.pool.map(func=self.run,iterable=self.__iterables,chunksize=self.__chunkSize):
self.__res.append(res)
DistancesRecordsPool.pool.join()
gPostgreSQLHelperObject.closeConnection()
return self.__res
def __yieldIterables(self):
for i in self.__itersList:
yield i

Related

`TypeError: 'str' object is not callable` when a decorator function is called

I get a TypeError: 'str' object is not callable error when a decorator function is caleld. E.g. I
call the function msgReturnAsList, which is actually meant to return a list and therefore I do not understand why is it throwing an error that a str object is not callable.
I read at FreeCodeCamp that this TypeError occurs mainly in two occasions, neither of which has anything to do with my case:
1."If You Use str as a Variable Name in Python"
2. "If You Call a String Like a Function in Python"
Can somebody clarify what is the logic behind this and how do I get msgReturnAsList to return the string converted to upper by wrapThis and then converted to a list by the problematic decorator function msgReturnAsList?
def wrapThis(a):
a = str(a).upper()
return a
#wrapThis
def msgReturnAsList(msg):
msg = list(msg)
return msg
b = "Convert to upper and output it as a list of letters."
print(msgReturnAsList(b))
I tired changing the list to string, interestingly the error remains the same.
A decorator method should return a method:
def wrapThis(func):
def wrapper_func(msg):
msg = str(msg).upper()
return func(msg)
return wrapper_func
#wrapThis
def msgReturnAsList(msg):
msg = list(msg)
return msg
b = "Convert to upper and output it as a list of letters."
print(msgReturnAsList(b))
How to Create and Use Decorators in Python With Examples

lambda function error: TypeError: 'function' object is not iterable

I'm trying to execute the following python notebook:
Them I came to the part where I have to use the function 'compute_cluster_similarities'.
def compute_cluster_similarities(kwds, kwd2id, vectors, lbl2centroid):
kwd2cluster_sims = dict()
for kwd in kwds:
ix = kwd2id[kwd]
nvec = vectors[ix]
sims = []
for lbl, centroid in lbl2centroid.items():
cosine_sim = np.inner(nvec, centroid)
sims.append((lbl,cosine_sim))
sims = sorted(sims, key = lambda lbl,sim: -sim)
kwd2cluster_sims[kwd] = sims
if len(kwd2cluster_sims) % 1000 == 0:
print("%i computed out of %i" % (len(kwd2cluster_sims), len(all_kwds)))
return kwd2cluster_sims
And its returning the error:
TypeError: () missing 1 required positional argument: 'sim'
First of all, I'm still trying to understand this part of the lambda code. I learned what is the objective of the lambda instruction but couldn't understand what is the point of this line of code, like.. is it (implicity) returning 2 values (sims, key)?? What is being sorted?
I think that this error is ocurring due the Python 3, but even if this was executed on Python 2, it doesn't make sense to me.
It's very confusing for me... How can I solve this error? And please, give me some explanation about what it's going on, not just the fix.
EDIT:
I'm using pdb library to debug the code and I realized that this error was being returned by the 'sorted()' function. The original error is:
*** TypeError: 'function' object is not iterable
What I did:
cosine_sim = np.inner(nvec, centroid)
sims.append((lbl,cosine_sim))
import pdb ; pdb.set_trace();
sims = sorted(sims, key = lambda lbl,sim: -sim)
and them at the Pdb mode:
(Pdb) sims, key = lambda lbl,sim: -sim
*** TypeError: 'function' object is not iterable
The function in the key parameter of sorted is fetched with the elements of the list, therefore it accepts only one parameter.
If you substitute:
key = lambda lbl,sim: -sim
with:
key=lambda x: -x[1]
It should work as you expect.
Refer to the documentation for more explanation of how to use sorted and the key parameter.

Cut-up method script - TypeError: object of type 'generator' has no len()

I'm trying to do a simple cut-up method (Wikipedia) script in python, but I've run in to a bit of trouble. here's what I've got:
import random
def splitter(string, num):
pieces = string.split()
for i in xrange(0, len(pieces), num):
yield' '.join(pieces[i:i+num])
def cutup(what, order):
mixed = list(random.shuffle(splitter(what, order)))
for piece in mixed:
print piece + " "
cutup(range(1,100), 3)
The idea is to split the input into num-lengthed chunks of words, shuffle those chunks, splice them back together and spit them back out. But I keep getting this error:
Traceback (most recent call last):
File "cutup.py", line 15, in <module>
cutup(range(1,100), 3)
File "cutup.py", line 11, in cutup
mixed = list(random.shuffle(splitter(what, order)))
File "/usr/lib/python2.7/random.py", line 288, in shuffle
for i in reversed(xrange(1, len(x))):
TypeError: object of type 'generator' has no len()
I think it has something to do with random.shuffle() returning a generator? I can't seem to fix it. Any thoughts?
random.shuffle() needs to know how long the input is (and tries to obtain length of the object). A generator can not provide this and you have to materialize it into a list:
lst = list(yielding(x))
random.shuffle(lst)
Also, note, random.shuffle makes in-place list modification.
Documentation is here.

Python - AttributeError: 'str' object has no attribute 'append'

I keep receiving this error when I try to run this code for the line "encoded.append("i")":
AttributeError: 'str' object has no attribute 'append'
I cannot work out why the list won't append with the string. I'm sure the problem is very simple Thank you for your help.
def encode(code, msg):
'''Encrypts a message, msg, using the substitutions defined in the
dictionary, code'''
msg = list(msg)
encoded = []
for i in msg:
if i in code.keys():
i = code[i]
encoded.append(i)
else:
encoded.append(i)
encoded = ''.join(encoded)
return encoded
You set encoded to string here:
encoded = ''.join(encoded)
And of course it doesn't have attribute 'append'.
Since you're doing it on one of cycle iteration, on next iteration you have str instead of list...
>>> encoded =["d","4"]
>>> encoded="".join(encoded)
>>> print (type(encoded))
<class 'str'> #It's not a list anymore, you converted it to string.
>>> encoded =["d","4",4] # 4 here as integer
>>> encoded="".join(encoded)
Traceback (most recent call last):
File "<pyshell#4>", line 1, in <module>
encoded="".join(encoded)
TypeError: sequence item 2: expected str instance, int found
>>>
As you see, your list is converted to a string in here "".join(encoded). And append is a method of lists, not strings. That's why you got that error. Also as you see if your encoded list has an element as integer, you will see TypeError because, you can't use join method on integers. Better you check your all codes again.
Your string conversion line is under the else clause. Take it out from under the conditional, and the for loop so that it's the last thing done to encoded. As it stands, you are converting to a string halfway through your for loop:
def encode(code, msg):
'''Encrypts a message, msg, using the substitutions defined in the
dictionary, code'''
msg = list(msg)
encoded = []
for i in msg:
if i in code.keys():
i = code[i]
encoded.append(i)
else:
encoded.append(i)
# after all appends and outside for loop
encoded = ''.join(encoded)
return encoded
You are getting the error because of the second expression in you else statement.
''.join(encoded) returns a string that gets assigned to encoded
Thus encoded is now of type string.
In the second loop you have the .append(i) method in either if/else statements which can only be applied to lists and not strings.
Your .join() method should appear after the for loop right before you return it.
I apoligise if the above text does not appear right. This is my first post and I still trying to figure out how this works.

TypeError: 'str' object is not callable

I am having a weird issue with Python. For some reason, when I call it from the command line, I can use the replace() function as much as I want but I cannot use it inside a specific class. The code yields the following (well-known) error:
File "/homes/mmj11/malice/lexer.py", line 96, in replaceInTree
tree[i] = tree[i].replace(" "," ")
TypeError: 'str' object is not callable
The function I'm using is the following:
def replaceInTree(self, tree):
for i in range(len(tree)):
if type(tree[i] is str):
tree[i] = tree[i].replace(" "," ")
tree[i] = tree[i].replace(tree[i], self.getToken(tree[i]))
else:
tree[i] = self.replaceInTree(tree)
return tree
I really think this should not happen as I can do the exact same thing in the command line. I am very sure that str's are meant to be callable.
Instead of
if type(tree[i] is str):
Dont you mean to do
if type(tree[i]) is str:
I would do this:
if type(tree[i]) is str:
instead of this:
if type(tree[i] is str):
The way you have it written evaluates to if type(false), which is equivalent to if bool, which will always be truthy.

Categories