Trcx
Trcx

Reputation: 4444

Python: if string starts with a string from a list

I'm reading a file and each line has a tag, followed by a colon and then the information that I want. A sample file would look like

Package: com.something.something
Section: Utilities
Name: Something

etc, (It's an apt packages index if you're wondering)
so I want to loop through each line and see if that line starts with an element from a list. I was thinking something like

PkgInfo={}
Tags=['Package', 'Section', 'Name']
for line in reader.readlines()
    if line.startswith(element in Tags):
        PkgInfo[element]=line.split(': ')[1]

This code doesn't work, but hopefully you understand what I am trying to do. How would I go about accomplishing this?

Upvotes: 2

Views: 10183

Answers (6)

soulcheck
soulcheck

Reputation: 36777

I'd try something like this:

 PkgInfo={}
 #I assume it should be 'Package' not 'Package: '
 Tags=['Package', 'Section', 'Name']

 for line in reader.readlines()
    k, v = line.split(': ')
    if k in Tags:
        PkgInfo[k] = v

or even quickier and dirtier two liner:

 #I assume it should be 'Package' not 'Package: '
 Tags=['Package', 'Section', 'Name']

 PkgInfo = dict(line.split(': ') for line in reader.readlines() if line.split(': ')[0] in Tags)

Upvotes: 0

Jonathon Reinhart
Jonathon Reinhart

Reputation: 137487

You need to iterate over Tags:

PkgInfo={}
Tags=['Package: ', 'Section', 'Name']
for line in reader.readlines():
    for tag in Tags:
        if line.startswith(tag):
            PkgInfo[tag]=line.split(': ')[1]
            break

Upvotes: 0

Felix Kling
Felix Kling

Reputation: 816810

I would suggest you just split line at : and then test whether the first part is one of your keywords. This can easily be done by using a set and the in operator:

tags = set(['Package', 'Section', 'Name'])
pkgInfo = {k: v.strip() for k, v in (line.split(':') for line in reader) if k in tags}

Or the longer version:

tags = set(['Package', 'Section', 'Name'])
pkgInfo = {}

for line in reader:
    k, v = line.split(':')
    if k in tags:
        pkgInfo[k] = v.strip()

But note that this will fail if there is not exactly one colon in each line.

Upvotes: 1

Giacomo Lacava
Giacomo Lacava

Reputation: 1833

The problem with all solutions based on split() is that they will probably break if colon appears more than once. This is less elegant but more robust:

PkgInfo = {}
Tags = ['Package','Section','Name']
splitter = ': '
splitLen = len(splitter)
for line in reader.readlines():
  firstColon = line.find(splitter)
  if firstColon > 0: 
    key = line[:firstColon]
    if key in Tags:
      pkgInfo[key] = line[firstColon + splitLen:] 

Upvotes: 1

Óscar López
Óscar López

Reputation: 236114

Try this:

PkgInfo = {}
Tags = ['Package', 'Section', 'Name']

for line in reader.readlines():
    for element in Tags:
        if line.startswith(element):
            PkgInfo[element] = line.split(': ')[1]
            break

Upvotes: 1

reclosedev
reclosedev

Reputation: 9522

Working solution with slightly different logic:

PkgInfo={}
Tags=['Package', 'Section', 'Name']


for line in reader.readlines():
    entry = line.strip().split(': ', 2)
    if len(entry) != 2:
        continue
    element, value = entry[0], entry[1]
    if element in Tags:
        PkgInfo[element] = value

print PkgInfo

And pay attention to the fact that iteration over elements was not only one problem. 'Package' in Tags was defined as 'Package: ', Tags in loop referenced as tags, split.line instead line.split(), value isn't stripped.

Upvotes: 1

Related Questions