Поставьте строку в конце каждой строки, содержащей foo - PullRequest
4 голосов
/ 06 октября 2009

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

Jane likes Fred
Chris dislikes Joe
Nate knows Jill

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

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

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

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

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

Ответы [ 7 ]

5 голосов
/ 06 октября 2009

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

Кроме того, если у вас есть общие любопытства по поводу 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])
3 голосов
/ 06 октября 2009

достаточно просто; при условии, что списки глаголов фиксированы и малы, это легко сделать с помощью словаря и цикла 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 ()
2 голосов
/ 06 октября 2009
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

Редактировать: скорее использовать "для s в открытом"

1 голос
/ 06 октября 2009

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

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

  1. читать
  2. разбить его на слова (на пробел - .split ())
  3. преобразовать среднее слово в цвет (на основе сопоставления -> cf: python dict ()
  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.
0 голосов
/ 06 октября 2009

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

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

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

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)

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

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

0 голосов
/ 06 октября 2009

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

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

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) Нам на самом деле не нужно «with» для этой проблемы, и написание этого таким образом делает программу более переносимой для более старых версий Python. Я думаю, это должно работать на Python 2.2 и новее (я тестировал только на Python 2.6).

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

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

0 голосов
/ 06 октября 2009

Python 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, ";"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...