Hi,

What's the easiest way to check whether an item is in a list and then get to that element and do something with it? So far I can think of

if x in List:
    for x in List:
        if x = y:
            do something

Thank you.

Simpler ...

if x in List:
    # do something with x

Depends...
If you have this:

a = [1,2,3,4,5]
if 1 in a:
    #Let's say if you needed to change the list's 1
    #as in, do something to the list's value itself
    #cannot do: 1 = do_something()
    a[a.index(1)] = do_something() #only way

Edited 6 Years Ago by jcao219: n/a

Maybe, but in that case you are doing something to the list. Not sure if that was in the original scope.

On the other hand, maybe I am just getting too old and petery.

Edited 6 Years Ago by vegaseat: n/a

Thank you for your replies.

So when x is found in List it already points to that item? Great, that's what I wanted. As long as I use x as a variable, not as a value, right?

But the next question is if this will work with XML (say with ElementTree)? For example, how can I

1. check if an element with a certain property exists
2. if it ixists, then I need to check if one of its subelements exists
3. if it exists too, then I need to change its text, else create a new one

And since elements are lists, I do this:

...
        self.tree = ElementTree()
        self.xmlDoc = self.tree.parse(self.xmlFile)
        self.lstProperty = self.xmlDoc.getiterator("property")
...

    def SaveUnits(self, strProperty, strNewProperty, strToUnit, strNewToUnit):
        for property in self.lstProperty:
            if property.attrib["name"] == strProperty:
                lstUnits = property.getiterator("unit")
                for units in lstUnits:
                    toUnit = units.getchildren()
                    if toUnit[0].text == strToUnit:
                        toUnit[0].text = strNewToUnit
                    else:
                        #Create a new subelement
                        ...


XML:
	<property name="Multipliers">
		<unit>
			<unitname>one unit</unitname>
			<factor>1</factor>
			<E>0</E>
			<unicode>0020</unicode>
		</unit>

		<unit>
			<unitname>giga</unitname>
			<factor>1</factor>
			<E>9</E>
			<unicode>0047</unicode>
		</unit>
		<unit>
			<unitname>mega</unitname>
			<factor>1</factor>
			<E>6</E>
			<unicode>004D</unicode>
		</unit>
...

and here's the problems:
1. can I check if property.attrib["name"] == strProperty without going through the loop first?
2. if the subelement is not the 1st in the loop, the 'else' always executes every loop iteration until it finds the match, that is it will create new elements until it finds one. How can I make it create a new one only if it doesn't exist?

And another question:
My XML file has idented elements. When I add a new element (self.xmlDoc.append(newProperty)), it appends the whole lot as one line without line breaks and idents. Should I add "\n" and "\t" myself? I thought this would have been done automatically.

Thank you.

Edited 6 Years Ago by linuxoidoz: n/a

What I mean is this ...

a = 1
b = 2
c = 3

mylist = [a, b, c]

if b in mylist:
    print b  # 2

Here list element b is a variable reference that 'points' to the value 2.
Python actually uses a local dictionary where b is the key and 2 is the value.

Edited 6 Years Ago by vegaseat: ref


So when x is found in List it already points to that item? Great, that's what I wanted. As long as I use x as a variable, not as a value, right?

No, not really. x doesn't automatically point to the item in the list.

Also, you don't want to use property as a variable name. I've never used Python's xml modules, so I can't really help with your second problem.

EDIT:
I found this online:

from xml.etree import ElementTree as ET


def indent(elem, level=0):
    i = "\n" + level*"  "
    if len(elem):
        if not elem.text or not elem.text.strip():
            elem.text = i + "  "
        if not elem.tail or not elem.tail.strip():
            elem.tail = i
        for elem in elem:
            indent(elem, level+1)
        if not elem.tail or not elem.tail.strip():
            elem.tail = i
    else:
        if level and (not elem.tail or not elem.tail.strip()):
            elem.tail = i


# build a tree structure
root = ET.Element("html")

head = ET.SubElement(root, "head")

title = ET.SubElement(head, "title")
title.text = "Page Title"

body = ET.SubElement(root, "body")
body.set("bgcolor", "#ffffff")

body.text = "Hello, World!"
indent(root)
# wrap it in an ElementTree instance, and save as XML
tree = ET.ElementTree(root)
tree.write("page.xhtml")

That indented it.

Edited 6 Years Ago by jcao219: n/a

Thank you, jcao219. That 'indent' function worked.

Anyone know how to check if an element with a certain attribute exists without going through all elements? e.g.
<property name="Multipliers">

or

how to perform an 'else' statement outside the check-for-element-with-attribute loop if no element is found? e.g.

for property in self.lstProperty:
   if property.attrib["name"] == strProperty:
      #do something
   else:
      #do something else - but this will alsways run until the above property is found. How to put this 'else' outside the 'for'?

Thank you.

for property in self.lstProperty:
   if property.attrib["name"] == strProperty:
      #do something
else:
      #do something else if did not break out of loop
>>> x=2
>>> for i in range(1,x):
	if x>3: break
else: print 'Hello else'

Hello else
>>> x=4
>>> for i in range(1,x):
	if x>3: break
else: print 'Hello else'

>>>

Edited 6 Years Ago by pyTony: Interactive log added

I know how it works with string lists or integer lists, but I don't know how it works with XML with attributes.

Edited 6 Years Ago by linuxoidoz: n/a

for statement is the same, so why would it not work?

Try some print statements and send more data of inputs, results and expected results.

Tony

I'm not saying your example won't work, I'm asking how to translate it to XML.
BTW, if I do this:

for i in range(0, 10):
   if x=5:  
      break
   else: 
      print 'Hello else'

it will print 'Hello' 5 times. I want it to print it once.

Edited 6 Years Ago by linuxoidoz: n/a

That loop should print 'Hello' ten times or zero times depending on value of x.
Better to say print (x == 5) and 'Hello\n'*10 or ''

>>> x=1
>>> print (x == 5) and 'Hello\n'*10 or ''

>>> x=5
>>> print (x == 5) and 'Hello\n'*10 or ''
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello

>>>

Edited 6 Years Ago by pyTony: n/a

Once again... you probably shouldn't use "property" as a variable name, it's a builtin decorator.

I got it, I just had to also check for the end of the list:

def Function(self):
        for property in self.lstProperty:
            if property.attrib["name"] == strProperty:
                #do something
                return True
            elif self.lstProperty.index(property) == len(self.lstProperty) - 1:
                #do something else
                return True
        return False

Oh, thanks for persistance, it just clicked, I had no idea there was a built-in Python class 'property', I just named my variable this because is holds a phisical property name, e.g. Length, Mass etc. I'll change it to something else. Overriding that class was purely accidental. Thanks again.

This question has already been answered. Start a new discussion instead.