Поместите bar в конце каждой строки, содержащей foo.

StackOverflow https://stackoverflow.com/questions/1522386

  •  19-09-2019
  •  | 
  •  

Вопрос

У меня есть список с большим количеством строк, каждая из которых имеет форму субъект-глагол-объект, например:

Jane likes Fred
Chris dislikes Joe
Nate knows Jill

Чтобы построить сетевой граф, который выражает различные отношения между узлами в направленных ребрах с цветовой кодировкой, мне нужно будет заменить глагол стрелкой и поместить цветовой код в конце каждой строки, что несколько упростит:

Jane -> Fred red;
Chris -> Joe blue;
Nate -> Jill black;

Глаголов немного, поэтому замена их стрелкой — это всего лишь вопрос нескольких команд поиска и замены.Однако прежде чем сделать это, мне нужно будет поместить в конце каждой строки цветовой код, соответствующий глаголу строки.Я хотел бы сделать это с помощью Python.

Это мои первые шаги в программировании, поэтому, пожалуйста, будьте откровенны и включите код, который читается в текстовом файле.

Спасибо за вашу помощь!

Это было полезно?

Решение

verbs = {"dislikes":"blue", "knows":"black", "likes":"red"}
for s in open("/tmp/infile"):
  s = s.strip()
  for verb in verbs.keys():
    if (s.count(verb) > 0):
      print s.replace(verb,"->")+" "+verbs[verb]+";"
      break

Редактировать:Лучше используйте «for s in open»

Другие советы

Похоже, вы захотите изучить словари и форматирование строк.В общем, если вам нужна помощь в программировании, просто разбейте любую возникшую у вас проблему на очень маленькие, отдельные фрагменты, выполните поиск по этим фрагментам независимо, а затем вы сможете сформулировать все это в более крупный ответ.Stack Overflow — отличный ресурс для такого типа поиска.

Кроме того, если у вас есть какие-либо общие вопросы о Python, найдите или просмотрите официальная документация Python.Если вы постоянно не знаете, с чего начать, прочитайте Учебник по Python или найдите книгу, которую можно прочитать.Неделя или две, потраченные на получение хороших базовых знаний о том, что вы делаете, окупятся снова и снова по мере завершения работы.

verb_color_map = {
    'likes': 'red',
    'dislikes': 'blue',
    'knows': 'black',
}

with open('infile.txt') as infile: # assuming you've stored your data in 'infile.txt'
    for line in infile:
        # Python uses the name object, so I use object_
        subject, verb, object_ = line.split()
        print "%s -> %s %s;" % (subject, object_, verb_color_map[verb])

Достаточно просто;предполагая, что списки глаголов фиксированы и малы, это легко сделать с помощью словаря и for петля:

VERBS = {
    "likes": "red"
  , "dislikes": "blue"
  , "knows": "black"
  }

def replace_verb (line):
    for verb, color in VERBS.items():
        if verb in line:
            return "%s %s;" % (
                  line.replace (verb, "->")
                , color
                )
    return line

def main ():
    filename = "my_file.txt"
    with open (filename, "r") as fp:
        for line in fp:
            print replace_verb (line)

# Allow the module to be executed directly on the command line
if __name__ == "__main__":
    main ()

Вы уверены, что это не домашнее задание :) Если да, то можно сознаться.Не вдаваясь в подробности, подумайте о задачах, которые вы пытаетесь выполнить:

Для каждой строки:

  1. прочти это
  2. разделить его на слова (по пробелам - .split() )
  3. преобразовать среднее слово в цвет (на основе сопоставления -> ср.:Python дикт()
  4. напечатайте первое слово, стрелку, третье слово и цвет

Код с использованием NetworkX (networkx.lanl.gov/)

'''
plot relationships in a social network
'''

import networkx
## make a fake file 'ex.txt' in this directory
## then write fake relationships to it.
example_relationships = file('ex.txt','w') 
print >> example_relationships, '''\
Jane Doe likes Fred
Chris dislikes Joe
Nate knows Jill \
'''
example_relationships.close()

rel_colors = {
    'likes':  'blue',
    'dislikes' : 'black',
    'knows'   : 'green',
}

def split_on_verb(sentence):
    ''' we know the verb is the only lower cased word

    >>> split_on_verb("Jane Doe likes Fred")
    ('Jane Does','Fred','likes')

    '''
    words = sentence.strip().split()  # take off any outside whitespace, then split
                                       # on whitespace
    if not words:
        return None  # if there aren't any words, just return nothing

    verbs = [x for x in words if x.islower()]
    verb = verbs[0]  # we want the '1st' one (python numbers from 0,1,2...)
    verb_index = words.index(verb) # where is the verb?
    subject = ' '.join(words[:verb_index])
    obj =  ' '.join(words[(verb_index+1):])  # 'object' is already used in python
    return (subject, obj, verb)


def graph_from_relationships(fh,color_dict):
    '''
    fh:  a filehandle, i.e., an opened file, from which we can read lines
        and loop over
    '''
    G = networkx.DiGraph()

    for line in fh:
        if not line.strip():  continue # move on to the next line,
                                         # if our line is empty-ish
        (subj,obj,verb) = split_on_verb(line)
        color = color_dict[verb]
        # cf: python 'string templates', there are other solutions here
        # this is the 
        print "'%s' -> '%s' [color='%s'];" % (subj,obj,color)
        G.add_edge(subj,obj,color)
        # 

    return G

G = graph_from_relationships(file('ex.txt'),rel_colors)
print G.edges()
# from here you can use the various networkx plotting tools on G, as you're inclined.

Питон 2.5:

import sys
from collections import defaultdict

codes = defaultdict(lambda: ("---", "Missing action!"))
codes["likes"] =    ("-->", "red")
codes["dislikes"] = ("-/>", "green")
codes["loves"] =    ("==>", "blue")

for line in sys.stdin:
    subject, verb, object_ = line.strip().split(" ")
    arrow, color = codes[verb]
    print subject, arrow, object_, color, ";"

В дополнение к вопросу Карасу также сказал (в комментарии к одному ответу):«При фактическом вводе и субъекты, и объекты непредсказуемо изменяются от одного до двух слов».

Хорошо, вот как я бы это решил.

color_map = \
{
    "likes" : "red",
    "dislikes" : "blue",
    "knows" : "black",
}

def is_verb(word):
    return word in color_map

def make_noun(lst):
    if not lst:
        return "--NONE--"
    elif len(lst) == 1:
        return lst[0]
    else:
        return "_".join(lst)


for line in open("filename").readlines():
    words = line.split()
    # subject could be one or two words
    if is_verb(words[1]):
        # subject was one word
        s = words[0]
        v = words[1]
        o = make_noun(words[2:])
    else:
        # subject was two words
        assert is_verb(words[2])
        s = make_noun(words[0:2])
        v = words[2]
        o = make_noun(words[3:])
    color = color_map[v]
    print "%s -> %s %s;" % (s, o, color)

Некоторые примечания:

0) На самом деле для этой задачи нам не нужно слово «с», и его написание таким образом делает программу более переносимой для старых версий Python.Я думаю, это должно работать на Python 2.2 и новее (я тестировал только на Python 2.6).

1) Вы можете изменить make_noun(), чтобы использовать любую стратегию, которую вы считаете полезной для обработки нескольких слов.Я показал, как просто соединяю их вместе с помощью подчеркивания, но вы можете иметь словарь прилагательных и выбрасывать их, иметь словарь существительных и выбирать их или что-то еще.

2) Вы также можете использовать регулярные выражения для более нечеткого сопоставления.Вместо того, чтобы просто использовать словарь для color_map, вы могли бы иметь список кортежей с регулярным выражением в паре с заменяющим цветом, а затем, когда регулярное выражение совпадет, заменить цвет.

Вот улучшенная версия моего предыдущего ответа.В этом случае используется сопоставление регулярных выражений для получения нечеткого совпадения глагола.Все это работает:

Steve loves Denise
Bears love honey
Maria interested Anders
Maria interests Anders

Регулярный рисунок выражения "любит?" соответствует "Love" плюс необязательный 's'.Шаблон «interest.*» соответствует «interest» плюс что-нибудь еще.Шаблоны с несколькими альтернативами, разделенными вертикальными полосами, соответствуют, если соответствует хотя бы одна из альтернатив.

import re

re_map = \
[
    ("likes?|loves?|interest.*", "red"),
    ("dislikes?|hates?", "blue"),
    ("knows?|tolerates?|ignores?", "black"),
]

# compile the regular expressions one time, then use many times
pat_map = [(re.compile(s), color) for s, color in re_map]

# We dont use is_verb() in this version, but here it is.
# A word is a verb if any of the patterns match.
def is_verb(word):
    return any(pat.match(word) for pat, color in pat_map)

# Return color from matched verb, or None if no match.
# This detects whether a word is a verb, and looks up the color, at the same time.
def color_from_verb(word):
    for pat, color in pat_map:
        if pat.match(word):
            return color
    return None

def make_noun(lst):
    if not lst:
        return "--NONE--"
    elif len(lst) == 1:
        return lst[0]
    else:
        return "_".join(lst)


for line in open("filename"):
    words = line.split()
    # subject could be one or two words
    color = color_from_verb(words[1])
    if color:
        # subject was one word
        s = words[0]
        o = make_noun(words[2:])
    else:
        # subject was two words
        color = color_from_verb(words[1])
        assert color
        s = make_noun(words[0:2])
        o = make_noun(words[3:])
    print "%s -> %s %s;" % (s, o, color)

Надеюсь, понятно, как взять этот ответ и расширить его.Вы можете легко добавить больше шаблонов, чтобы соответствовать большему количеству глаголов.Вы можете добавить логику для определения «есть» и «в» и отбросить их, чтобы совпадало «Андерс интересуется Марией».И так далее.

Если у вас есть какие-либо вопросы, я буду рад объяснить это подробнее.Удачи.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top