Essentially this is what I'm trying to do:
I have a set that I add objects to. These objects have their own equality method, and a set should never have an element equal to another element in the set. However, when attempting to insert an element, if it is equal to another element, I'd like to record a merged version of the two elements. That is, the objects have an "aux" field that is not considered in its equality method. When I'm done adding things, I would like an element's "aux" field to contain a combination of all of the "aux" fields of equal elements I've tried to add.
My thinking was, okay, before adding an element to the set, check to see if it's already in the set. If so, pull it out of the set, combine the two elements, then put it back in. However, the remove method in Python sets doesn't return anything and the pop method returns an arbitrary element.
Can I do what I'm trying to do with sets in Python, or am I barking up the wrong tree (what is the right tree?)
Sounds like you want a defaultdict
from collections import defaultdict
D = defaultdict(list)
D[somekey].append(auxfield)
Edit:
To use your merge function, you can combine the code people have given in the comments
D = {}
for something in yourthings:
if something.key in D:
D[something.key] = something.auxfield
else:
D[something.key] = merge(D[something.key], something.auxfield)
Related
is there a way of passing a field of an array of collections into a function so that it can still be used to access a element in the collection in python?. i am attempting to search through an array of collections to locate a particular item by comparing it with an identifier. this identifier and field being compared will change as the function is called in different stages of the program. is there a way of passing up the field to the function, to access the required element for comparison?
this is the code that i have tried thus far:
code ...
In your code, M_work is a list. Lists are accessed using an index and this syntax: myList[index]. So that would translate to M_work[place] in your case. Then you say that M_work stores objects which have fields, and you want to access one of these fields by name. To do that, use getattr like this: getattr(M_work[place], field). You can compare the return value to identifier.
Other mistakes in the code you show:
place is misspelled pace at one point.
True is misspelled true at one point.
The body of your loop always returns at the first iteration: there is a return in both the if found == True and else branches. I don't think this is what you want.
You could improve your code by:
noticing that if found == True is equivalent to if found.
finding how you don't actually need the found variable.
looking at Python's for...in loop.
I need to check if the ID of a similar result exists in the exact results already and then exclude that result, I'm just unsure of the best way to do so.
I assume I'd have to find a way to iterate through both lists, then try something like if similar.ID != exact.ID and pass that to a variable to pass to the Jinja2 template.
The queries are being done with SQL-Alchemy like so;
exact_assets = Motor.query.filter_by(**filter_data).all()
similar_assets = Motor.query.filter_by(**similar_filter_data).all()
# Something like
# for similar_asset, exact_asset in similar_assets, exact_assets:
# if similiar_asset.id == asset.id:
# similar_asset.pop(id)
I know that syntax isn't correct, or even functional with a list or dict (?) but hopefully it is able to express what I'm trying to achieve here.
First create an list of keys to compare with (assuming that equality means same id from your code)
exact_assets_ids = [item.id for item in exact_assets]
Then filter your similar assets
final_assets = [item for item in similar_assets if item.id in exact_assets_ids]
Update: Just noticed that it is the intersection set :)
final_set = list(set(similar_assets) or set(exact_assets))
But in this case you should implement Motor.__eq__
i am using pyXB for binding XML.
my schema used at there has choice elements.
so when i convert XML into a python instance
i don't know exactly which element is chosen at choice element.
So in order to distinguish, i have had to use if/else statement considering all cases.
for example, if the choice element has a and b, to distinguish one within a and b
A = binder.CreateFromDocument(xml) #bind into a python instance
#At this point, i don't know which element is included
#So I have to check using if/else
if A.a:
#processing in the case of a
A.a.aa = 'a'
else if A.b:
#processing in the case of b
A.b.bb = 'b'
the example is so simple and if/else looks enough but if the choice element has so many element about more than 100.
that processing(repeated if/else) will be so bad.
is there any other way to know which element is chosen?
Yes; there is a method orderedContent on complex type instances that can be used to determine what elements are present in the instance. This can also be used to recover the document order of elements when order is not enforced by the schema, as described in the user documentation.
Note that the members of the orderedContent list are wrapped in objects that provide information about them, so to get the underlying content binding you have to drill down through the wrapper's value property.
If I have a python set and I want to find out if one element in the set is part of another element in the same set, how do I do it?
I've tried using indicies but I run into the following:
mySet = {"hello", "lo"}
mySet[1] in mySet[0] #I expect to return true
TypeError: 'set' object does not support indexing
I haven't found the python docs to be particularly helpful in this situation because I don't know how to compare elements within a set.
BTW, this is my first Stackoverflow question ever. I tried to adhere to the best practices. If there is a way I can improve the question, please let me know. Thank you for your help!
Sets don't have order. The index of an element is effectively the element itself. If you do need sets (although I have suspicions another data structure may be suitable) then they are iterable, and you can compare each element with other elements, but this won't be terrific performance wise, eg:
mySet = {"hello", "lo"}
for item in mySet:
for other_item in mySet.difference([item]):
if item in other_item:
print item, other_item
'set' object does not support indexing.
That clearly states that you can not index an element of set as mySet[1].
to access a single element of a set you have to use it like mySet.pop()
It looks like you're not actually trying to compare sets, but rather members of sets. The problem is you can't grab indexed members, because sets are an unordered (and as such unindexed) collection of elements.
You're trying to compare these two elements (strings). What you want is therefore a list or tuple:
>>> myTuple = ('hello', 'lo')
>>> myTuple[1] in myTuple[0]
True
This checks if the string 'lo' is a substring of 'hello'. This appears to be what you're trying to accomplish in your question.
I'm trying to build a solution to properly order an array of value pairs so that they end up in the correct sequence. Consider this example in Python:
theArray = [['Dempster St','Main St'],['Dempster St','Church St'],['Emerson St','Church St']]
I need to order the array so that in the end it looks like this:
theArray = [['Emerson St','Church St'],['Church St','Dempster St'],['Dempster St','Main St']]
Some considerations:
There is no guarantee that the order within each pair point in the same direction. Ex: in the example above, the second array element has the order of their pairs pointing in the opposite direction of the rest (Dempster to Church instead of Church to Dempster)
The code should be built so that it could be used in both Python and C, so ideally it should be done without any language-specific tricks
At the end, it doesn't matter in which order the final array will be built, as long as the elements follow the correct order. For example, the solution below would also work:
theArray = [['Main St','Dempster St'],['Dempster St','Church St'],['Church St','Emerson St']]
Ideas?
I managed to make it work. I iterated each element of every pair with each other by using multiple nested loops - so that I could check for their uniqueness (and in order to do that, I increment an associated variable whenever an item was found more than once, like a refcount); at the end, the two elements with the lowest count are beginning and end of the route. From there it was quite easy to find the remaining connections.