Filtering parent and children elements of list of dictionaries

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
2
down vote

favorite












I have a list of dictionaries and its elements has id and parent_id fields.



Main purposes:



  • If the parent_id field of an element is defined, it should be returning the rest of elements except itself.

  • If the parent_id field of element is not defined, it should be returning the rest of elements. In other words, its all child elements. Because it is parent element.

I'll be sharing my implementation below. But I need more concise and Pythonic way.



products = [
"id": 5, "counter": 10, "parent_id": None,
"id": 6, "counter": 10, "parent_id": 5,
"id": 7, "counter": 10, "parent_id": 5,
]

def get_by_id(product_id):
product = list(filter(lambda p: p["id"] == product_id, products))
return product[0] if product else False

def get_by_product(product):
p =
for i in products:
if product["parent_id"]:
if i["id"] == product["parent_id"] or i["id"] != product["id"]:
p.append(i)
else:
if i["parent_id"] == product["id"]:
p.append(i)
return p

p = get_by_id(7)
g = get_by_product(p)
print(g) # ['id': 5, 'counter': 10, 'parent_id': None, 'id': 6, 'counter': 10, 'parent_id': 5]

p = get_by_id(5)
g = get_by_product(p)
print(g) # ['id': 6, 'counter': 10, 'parent_id': 5, 'id': 7, 'counter': 10, 'parent_id': 5]


I have changed ridiculous if statements above like this:



def get_by_product(product):
p =
for i in products:
if product["parent_id"] and i["id"] == product["parent_id"] or i["id"] != product["id"] or i["parent_id"] == product["id"]:
p.append(i)
return p






share|improve this question

















  • 1




    How do you use these, because you could probably change the data to a dictionary for $O(n)$ creation, and $O(1)$ lookup, rather than $O(n)$ lookup.
    – Peilonrayz
    Jan 6 at 4:07










  • It is not used in live environment. It was just a trivial code for practising. Open to any suggestions.
    – vildhjarta
    Jan 6 at 13:26
















up vote
2
down vote

favorite












I have a list of dictionaries and its elements has id and parent_id fields.



Main purposes:



  • If the parent_id field of an element is defined, it should be returning the rest of elements except itself.

  • If the parent_id field of element is not defined, it should be returning the rest of elements. In other words, its all child elements. Because it is parent element.

I'll be sharing my implementation below. But I need more concise and Pythonic way.



products = [
"id": 5, "counter": 10, "parent_id": None,
"id": 6, "counter": 10, "parent_id": 5,
"id": 7, "counter": 10, "parent_id": 5,
]

def get_by_id(product_id):
product = list(filter(lambda p: p["id"] == product_id, products))
return product[0] if product else False

def get_by_product(product):
p =
for i in products:
if product["parent_id"]:
if i["id"] == product["parent_id"] or i["id"] != product["id"]:
p.append(i)
else:
if i["parent_id"] == product["id"]:
p.append(i)
return p

p = get_by_id(7)
g = get_by_product(p)
print(g) # ['id': 5, 'counter': 10, 'parent_id': None, 'id': 6, 'counter': 10, 'parent_id': 5]

p = get_by_id(5)
g = get_by_product(p)
print(g) # ['id': 6, 'counter': 10, 'parent_id': 5, 'id': 7, 'counter': 10, 'parent_id': 5]


I have changed ridiculous if statements above like this:



def get_by_product(product):
p =
for i in products:
if product["parent_id"] and i["id"] == product["parent_id"] or i["id"] != product["id"] or i["parent_id"] == product["id"]:
p.append(i)
return p






share|improve this question

















  • 1




    How do you use these, because you could probably change the data to a dictionary for $O(n)$ creation, and $O(1)$ lookup, rather than $O(n)$ lookup.
    – Peilonrayz
    Jan 6 at 4:07










  • It is not used in live environment. It was just a trivial code for practising. Open to any suggestions.
    – vildhjarta
    Jan 6 at 13:26












up vote
2
down vote

favorite









up vote
2
down vote

favorite











I have a list of dictionaries and its elements has id and parent_id fields.



Main purposes:



  • If the parent_id field of an element is defined, it should be returning the rest of elements except itself.

  • If the parent_id field of element is not defined, it should be returning the rest of elements. In other words, its all child elements. Because it is parent element.

I'll be sharing my implementation below. But I need more concise and Pythonic way.



products = [
"id": 5, "counter": 10, "parent_id": None,
"id": 6, "counter": 10, "parent_id": 5,
"id": 7, "counter": 10, "parent_id": 5,
]

def get_by_id(product_id):
product = list(filter(lambda p: p["id"] == product_id, products))
return product[0] if product else False

def get_by_product(product):
p =
for i in products:
if product["parent_id"]:
if i["id"] == product["parent_id"] or i["id"] != product["id"]:
p.append(i)
else:
if i["parent_id"] == product["id"]:
p.append(i)
return p

p = get_by_id(7)
g = get_by_product(p)
print(g) # ['id': 5, 'counter': 10, 'parent_id': None, 'id': 6, 'counter': 10, 'parent_id': 5]

p = get_by_id(5)
g = get_by_product(p)
print(g) # ['id': 6, 'counter': 10, 'parent_id': 5, 'id': 7, 'counter': 10, 'parent_id': 5]


I have changed ridiculous if statements above like this:



def get_by_product(product):
p =
for i in products:
if product["parent_id"] and i["id"] == product["parent_id"] or i["id"] != product["id"] or i["parent_id"] == product["id"]:
p.append(i)
return p






share|improve this question













I have a list of dictionaries and its elements has id and parent_id fields.



Main purposes:



  • If the parent_id field of an element is defined, it should be returning the rest of elements except itself.

  • If the parent_id field of element is not defined, it should be returning the rest of elements. In other words, its all child elements. Because it is parent element.

I'll be sharing my implementation below. But I need more concise and Pythonic way.



products = [
"id": 5, "counter": 10, "parent_id": None,
"id": 6, "counter": 10, "parent_id": 5,
"id": 7, "counter": 10, "parent_id": 5,
]

def get_by_id(product_id):
product = list(filter(lambda p: p["id"] == product_id, products))
return product[0] if product else False

def get_by_product(product):
p =
for i in products:
if product["parent_id"]:
if i["id"] == product["parent_id"] or i["id"] != product["id"]:
p.append(i)
else:
if i["parent_id"] == product["id"]:
p.append(i)
return p

p = get_by_id(7)
g = get_by_product(p)
print(g) # ['id': 5, 'counter': 10, 'parent_id': None, 'id': 6, 'counter': 10, 'parent_id': 5]

p = get_by_id(5)
g = get_by_product(p)
print(g) # ['id': 6, 'counter': 10, 'parent_id': 5, 'id': 7, 'counter': 10, 'parent_id': 5]


I have changed ridiculous if statements above like this:



def get_by_product(product):
p =
for i in products:
if product["parent_id"] and i["id"] == product["parent_id"] or i["id"] != product["id"] or i["parent_id"] == product["id"]:
p.append(i)
return p








share|improve this question












share|improve this question




share|improve this question








edited Jan 6 at 2:12
























asked Jan 6 at 2:07









vildhjarta

325




325







  • 1




    How do you use these, because you could probably change the data to a dictionary for $O(n)$ creation, and $O(1)$ lookup, rather than $O(n)$ lookup.
    – Peilonrayz
    Jan 6 at 4:07










  • It is not used in live environment. It was just a trivial code for practising. Open to any suggestions.
    – vildhjarta
    Jan 6 at 13:26












  • 1




    How do you use these, because you could probably change the data to a dictionary for $O(n)$ creation, and $O(1)$ lookup, rather than $O(n)$ lookup.
    – Peilonrayz
    Jan 6 at 4:07










  • It is not used in live environment. It was just a trivial code for practising. Open to any suggestions.
    – vildhjarta
    Jan 6 at 13:26







1




1




How do you use these, because you could probably change the data to a dictionary for $O(n)$ creation, and $O(1)$ lookup, rather than $O(n)$ lookup.
– Peilonrayz
Jan 6 at 4:07




How do you use these, because you could probably change the data to a dictionary for $O(n)$ creation, and $O(1)$ lookup, rather than $O(n)$ lookup.
– Peilonrayz
Jan 6 at 4:07












It is not used in live environment. It was just a trivial code for practising. Open to any suggestions.
– vildhjarta
Jan 6 at 13:26




It is not used in live environment. It was just a trivial code for practising. Open to any suggestions.
– vildhjarta
Jan 6 at 13:26










1 Answer
1






active

oldest

votes

















up vote
2
down vote



accepted










  1. If your actual program has the products list is a constant global variable, declare it as PRODUCTS (uppercase global constants)

  2. Using list(filter(lambda can be removed by a simple comprehension. A list comprehension is the preferred method of iterating over lists as per PEP-0202

  3. Instead of returning False in get_by_id, return a None, as that is more user intuitive.

Check the following:



def get_by_id(product_id):
"""Return a product from the list with given id, or None if not found"""
try:
product = next((p for p in PRODUCTS if p["id"] == product_id))
return product
except StopIteration:
return None


There is no extra list being created in-memory. The generator expression returns the first value (if any) or raises a StopIteration.



For the get_by_product, you can have 2 snippets. One will remove the given product from list if product.parent_id exists, and another will search for child products.



def get_by_product(product):
if product["parent_id"] is not None:
return [p for p in PRODUCTS if p != product]
return [p for p in PRODUCTS if p['parent_id'] == product['id']]





share|improve this answer























  • Do you have any source which explains the speed of list comprehensions over filter function?
    – vildhjarta
    Jan 6 at 14:12






  • 1




    @vildhjarta stackoverflow.com/a/3013686/1190388
    – hjpotter92
    Jan 6 at 14:25










  • if you add another product tree you can see the bug. if the product is not None, it returns all dictionaries except itself.
    – vildhjarta
    Jan 8 at 20:39











Your Answer




StackExchange.ifUsing("editor", function ()
return StackExchange.using("mathjaxEditing", function ()
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
);
);
, "mathjax-editing");

StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "196"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);








 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f184413%2ffiltering-parent-and-children-elements-of-list-of-dictionaries%23new-answer', 'question_page');

);

Post as a guest






























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
2
down vote



accepted










  1. If your actual program has the products list is a constant global variable, declare it as PRODUCTS (uppercase global constants)

  2. Using list(filter(lambda can be removed by a simple comprehension. A list comprehension is the preferred method of iterating over lists as per PEP-0202

  3. Instead of returning False in get_by_id, return a None, as that is more user intuitive.

Check the following:



def get_by_id(product_id):
"""Return a product from the list with given id, or None if not found"""
try:
product = next((p for p in PRODUCTS if p["id"] == product_id))
return product
except StopIteration:
return None


There is no extra list being created in-memory. The generator expression returns the first value (if any) or raises a StopIteration.



For the get_by_product, you can have 2 snippets. One will remove the given product from list if product.parent_id exists, and another will search for child products.



def get_by_product(product):
if product["parent_id"] is not None:
return [p for p in PRODUCTS if p != product]
return [p for p in PRODUCTS if p['parent_id'] == product['id']]





share|improve this answer























  • Do you have any source which explains the speed of list comprehensions over filter function?
    – vildhjarta
    Jan 6 at 14:12






  • 1




    @vildhjarta stackoverflow.com/a/3013686/1190388
    – hjpotter92
    Jan 6 at 14:25










  • if you add another product tree you can see the bug. if the product is not None, it returns all dictionaries except itself.
    – vildhjarta
    Jan 8 at 20:39















up vote
2
down vote



accepted










  1. If your actual program has the products list is a constant global variable, declare it as PRODUCTS (uppercase global constants)

  2. Using list(filter(lambda can be removed by a simple comprehension. A list comprehension is the preferred method of iterating over lists as per PEP-0202

  3. Instead of returning False in get_by_id, return a None, as that is more user intuitive.

Check the following:



def get_by_id(product_id):
"""Return a product from the list with given id, or None if not found"""
try:
product = next((p for p in PRODUCTS if p["id"] == product_id))
return product
except StopIteration:
return None


There is no extra list being created in-memory. The generator expression returns the first value (if any) or raises a StopIteration.



For the get_by_product, you can have 2 snippets. One will remove the given product from list if product.parent_id exists, and another will search for child products.



def get_by_product(product):
if product["parent_id"] is not None:
return [p for p in PRODUCTS if p != product]
return [p for p in PRODUCTS if p['parent_id'] == product['id']]





share|improve this answer























  • Do you have any source which explains the speed of list comprehensions over filter function?
    – vildhjarta
    Jan 6 at 14:12






  • 1




    @vildhjarta stackoverflow.com/a/3013686/1190388
    – hjpotter92
    Jan 6 at 14:25










  • if you add another product tree you can see the bug. if the product is not None, it returns all dictionaries except itself.
    – vildhjarta
    Jan 8 at 20:39













up vote
2
down vote



accepted







up vote
2
down vote



accepted






  1. If your actual program has the products list is a constant global variable, declare it as PRODUCTS (uppercase global constants)

  2. Using list(filter(lambda can be removed by a simple comprehension. A list comprehension is the preferred method of iterating over lists as per PEP-0202

  3. Instead of returning False in get_by_id, return a None, as that is more user intuitive.

Check the following:



def get_by_id(product_id):
"""Return a product from the list with given id, or None if not found"""
try:
product = next((p for p in PRODUCTS if p["id"] == product_id))
return product
except StopIteration:
return None


There is no extra list being created in-memory. The generator expression returns the first value (if any) or raises a StopIteration.



For the get_by_product, you can have 2 snippets. One will remove the given product from list if product.parent_id exists, and another will search for child products.



def get_by_product(product):
if product["parent_id"] is not None:
return [p for p in PRODUCTS if p != product]
return [p for p in PRODUCTS if p['parent_id'] == product['id']]





share|improve this answer















  1. If your actual program has the products list is a constant global variable, declare it as PRODUCTS (uppercase global constants)

  2. Using list(filter(lambda can be removed by a simple comprehension. A list comprehension is the preferred method of iterating over lists as per PEP-0202

  3. Instead of returning False in get_by_id, return a None, as that is more user intuitive.

Check the following:



def get_by_id(product_id):
"""Return a product from the list with given id, or None if not found"""
try:
product = next((p for p in PRODUCTS if p["id"] == product_id))
return product
except StopIteration:
return None


There is no extra list being created in-memory. The generator expression returns the first value (if any) or raises a StopIteration.



For the get_by_product, you can have 2 snippets. One will remove the given product from list if product.parent_id exists, and another will search for child products.



def get_by_product(product):
if product["parent_id"] is not None:
return [p for p in PRODUCTS if p != product]
return [p for p in PRODUCTS if p['parent_id'] == product['id']]






share|improve this answer















share|improve this answer



share|improve this answer








edited Jan 6 at 3:54


























answered Jan 6 at 3:47









hjpotter92

4,98611539




4,98611539











  • Do you have any source which explains the speed of list comprehensions over filter function?
    – vildhjarta
    Jan 6 at 14:12






  • 1




    @vildhjarta stackoverflow.com/a/3013686/1190388
    – hjpotter92
    Jan 6 at 14:25










  • if you add another product tree you can see the bug. if the product is not None, it returns all dictionaries except itself.
    – vildhjarta
    Jan 8 at 20:39

















  • Do you have any source which explains the speed of list comprehensions over filter function?
    – vildhjarta
    Jan 6 at 14:12






  • 1




    @vildhjarta stackoverflow.com/a/3013686/1190388
    – hjpotter92
    Jan 6 at 14:25










  • if you add another product tree you can see the bug. if the product is not None, it returns all dictionaries except itself.
    – vildhjarta
    Jan 8 at 20:39
















Do you have any source which explains the speed of list comprehensions over filter function?
– vildhjarta
Jan 6 at 14:12




Do you have any source which explains the speed of list comprehensions over filter function?
– vildhjarta
Jan 6 at 14:12




1




1




@vildhjarta stackoverflow.com/a/3013686/1190388
– hjpotter92
Jan 6 at 14:25




@vildhjarta stackoverflow.com/a/3013686/1190388
– hjpotter92
Jan 6 at 14:25












if you add another product tree you can see the bug. if the product is not None, it returns all dictionaries except itself.
– vildhjarta
Jan 8 at 20:39





if you add another product tree you can see the bug. if the product is not None, it returns all dictionaries except itself.
– vildhjarta
Jan 8 at 20:39













 

draft saved


draft discarded


























 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f184413%2ffiltering-parent-and-children-elements-of-list-of-dictionaries%23new-answer', 'question_page');

);

Post as a guest













































































Popular posts from this blog

Greedy Best First Search implementation in Rust

Function to Return a JSON Like Objects Using VBA Collections and Arrays

C++11 CLH Lock Implementation