Olivier Pons
Olivier Pons

Reputation: 15778

Help for arrays: converting php code to python

For the first time this is not python => php but php => python. I've got small problem with arrays in python. (I've already been to docs.python.org)

Here's my problem: I get in python couples of strings like this:

(People 1):
  <criteria a> <data of the criteria>
  <criteria b> <data of the criteria>
  <criteria c> <data of the criteria>
  <criteria d> <data of the criteria>
(People 2):
  <criteria a> <data of the criteria>
  <criteria b> <data of the criteria>
  <criteria d> <data of the criteria>
...

(note for people 2 criteria c doesn't exist) So i'd like do that (in php it's very easy):

array_push( tab[ "criteria a" ],
    array("People1", "data of the criteria")
);

Then I'd like to show all a list of the criterias that exists, and use the array to create a nice "insert SQL query" for my database.

Any idea how to do this? Where should I look? I miss string indexed arrays....

Upvotes: 0

Views: 197

Answers (2)

Hugh Bothwell
Hugh Bothwell

Reputation: 56654

Ok, this is overkill, but you may find it interesting ;-)

import collections
import re

def makeMatcher(regex):
    reg = re.compile(regex).match
    def matcher(s):
        match = reg(s)
        return match and match.groups()  # return None or tuple of match-values
    return matcher

class StatefulIter(collections.Iterator):
    def __init__(self, seq, stateVars, *transitions, **kwargs):
        """
        StatefulIter crunches input sequence using transition rules

        :seq            :input sequence of data to operate on
        :stateVars      :state variables to operate on - dict OR space-separated string OR collection of strings
        :*transitions   :list of (isMatch, onMatch) tuples
                            (isMatch can be a function or a regex string)
                            isMatch(data) returns matched fields or None
                            onMatch(statedict, *fields) processes matched fields, returns isOutput
        :**outfn        :if isOutput, return outfn(statedict)

        """
        outfn = kwargs.pop('outfn')
        super(StatefulIter,self).__init__(**kwargs)
        self.seq = seq
        if isinstance(stateVars, dict):
            self.statedict = stateVars
        else:
            if isinstance(stateVars, basestring):
                stateVars = stateVars.split()
            self.statedict = {s:None for s in stateVars}
        self.trans = [(isMatch if callable(isMatch) else makeMatcher(isMatch), onMatch) for isMatch,onMatch in transitions]
        self.outfn = outfn

    def next(self):
        _sd = self.statedict
        while True:
            data = self.seq.next()
            for isMatch,onMatch in self.trans:
                match = isMatch(data)
                if match is not None:
                    res = onMatch(_sd,*match)
                    if res:
                        return self.outfn(_sd)
                    else:
                        break

class CriteriaIter(StatefulIter):
    states = 'person criteria date'

    isPeople = r'\((.+)\):'
    @staticmethod
    def onPeople(statedict, pers):
        statedict['person'] = pers
        return False

    isCriteria = r'\s*<(.*?)>\s*<(.*?)>'
    @staticmethod
    def onCriteria(statedict, crit, date):
        statedict['criteria'] = crit
        statedict['date']     = date
        return True

    @staticmethod
    def outfn(statedict):
        return statedict['person'], statedict['criteria'], statedict['date']

    def __init__(self, seq, outfn=None):
        people   = (CriteriaIter.isPeople,   CriteriaIter.onPeople)
        criteria = (CriteriaIter.isCriteria, CriteriaIter.onCriteria)
        outfn = outfn or CriteriaIter.outfn
        super(CriteriaIter,self).__init__(seq, CriteriaIter.states, people, criteria, outfn=outfn)

class CriteriaFile(file):
    def __iter__(self):
        return CriteriaIter(self)

def main():
    with CriteriaFile('data.txt') as inf:
        allEntries = [entry for entry in inf]
    allCriteria = set(entry[1] for entry in allEntries)

if __name__=="__main__":
    main()

Upvotes: 0

jsbueno
jsbueno

Reputation: 110301

In Python you have "dictionaries" instead of "string indexed arrays". Their syntax is different than for arrays.

You can do

data = {}
data["people 1"] = {}
data["people 1"]["criteria a"] = "bla"
data["people 1"]["criteria b"] = "ble"
data["people 2"] = {}

...

You can retrieve all contents of a dictionaries values using the values method:

>>> print data["people 1"].values()
["ble", "bla"]

(note that order is arbitrary when you do this) Anyway, you'd better check the documentation on Python basic data structures to do this: http://docs.python.org/tutorial/datastructures.html

Upvotes: 3

Related Questions