Python 에서 문단 추출

wingback의 이미지

안녕하세요.
Python 공부하고 있는 초보 입니다.

open 방식으로 특정 txt 파일을 readlines() 로 읽어 들인 내용 중

특정 부분만 print를 하고 싶은데 도무지 방법이 생각이 나지 않습니다.

예를 들어 TXT 파일에 # 을 시작으로 $ 라는 문자가 나올때 까지 Print 하고자 할때 어떤 방식의 코드를 쓰는게 좋을지 도움 부탁 드립니다.

아니면 #을 시작으로 아래로 10줄 print 이러한 방식으로도 가능하다면 도웁 부탁 드립니다.

라인별 원하는 부분 추출은 열심히 씨름하며 습득 했는데 부분 추출은 도무지 감이 안와서 이렇게 문의 드립니다.

감사합니다.

swish95의 이미지

1. mode 변수를 만든다. ( NONE : 출력안함, START: # 이 나와서 출력, $가 나오면 NONE 으로 바꿈)
2. 라인을 읽는다.
3. 라인중에 #, $ 의 인덱스를 찾는다.
4. #, $ 인덱스와 mode 변수로 적절히 출력하고 mode 변수를 마지막에 세팅한다.
5. 2-4 를 끝날때까지 반복

------------------------------------------------------------
ProgrammingHolic

파이썬3의 이미지

# -*- coding: utf-8 -*-
 
raw_data = """\
111
222
#333
444
555
666
777
888$
999
EOL"""
 
data = raw_data.splitlines(False)
 
i = ""
j = ""
 
for index in range(0, len(data)):
    if "#" in data<ol>
</ol>
:
        i = index
    if "$" in data<ol>
</ol>
:
        j = index
 
if __name__ == "__main__":
    result = data[i:j+1]
    for line in result:
        print(line)
황병희의 이미지

# -*- coding: utf-8 -*-
 
raw_data = """\
111
222
#333
444
555
666
777
888$
999
EOL"""
 
data = raw_data.splitlines(False)
 
i = ""
j = ""
 
for idx in range(0, len(data)):
    if "#" in data[idx]:
        i = idx
    if "$" in data[idx]:
        j = idx
 
if __name__ == "__main__":
    result = data[i:j+1]
    for line in result:
        print(line)

아래는 출력결과입니다:

(bionic)soyeomul@localhost:~/111$ python3 1.py
#333
444
555
666
777
888$
(bionic)soyeomul@localhost:~/111$ 

--
^고맙습니다 감사합니다_^))//

황병희의 이미지

# -*- coding: utf-8 -*-
 
raw_data = """\
111
222
#333
444
555
666
777
888$
999
EOL"""
 
data = raw_data.splitlines(False)
 
i = ""
j = ""
 
for idx in range(0, len(data)):
    if "#" in data[idx]:
        i = idx
    if "$" in data[idx]:
        j = idx
 
        """ $기호 임의의 위치일 경우 예외처리 """
        idx_dollar = data[idx].index("$")
        data[idx] = data[idx][0:idx_dollar+1]
 
if __name__ == "__main__":
    result = data[i:j+1]
    for line in result:
        print(line)

--
^고맙습니다 감사합니다_^))//

wingback의 이미지

정말 정말 감사드립니다!!!

파이썬3의 이미지

i = ""
j = ""

제가 쓴 코드에서 위 두 줄은 없어도 돌아가더이다...

저도 감사합니다^^^

파이썬3 드림

[우분투 18.04 파여폭스 나비에서 작성했습니다]

swish95의 이미지

점수 채점및 숙제 드립니다. 왠지 이런거 좋아하시는 분 같아서 ㅋㅋ

제 점수는요.. "B- " 입니다.

사족이지만
i,j 는 숫자형인데 기본값은 문자를 넣으셨군요.
그리고 if __name__ == "__main__": 위에 for 문을 작성한건 좀 이상하네요
그럴거면 "__main__" 행이 없던지 아니면 그 밑에 for 문을 옮기거나 해야 하지 않나 싶습니다.

A+ 받으시려면
1. 문자열을 파일로 받도록 해서 라인단위 검색
- 대용량 파일 대응
2. 에러 혹은 예외 처리
- $, # 이 쌍으로 나오지 않고 $fdasf$, #fdsafda# 와 같이 나오는 경우
- $ 이 없는 상태에서 # 이 나오거나, 그 반대의 경우

ps : 저번에도 이 비슷한 게시글에 코드 짜서 연습하셔서 글남김니다.
ps2: 혹시 "너나 잘하세요" 라는 마음이시라면 ㅠ.ㅠ 새로운 게시글로 남기시면 python 쪽은 제가 짜볼께요 ㅋㅋ
아마도 여기 계신분들이 알고 있는 모든 언어 버젼이 다 나올겁니다. ^^
ps3: 왠지 Git PR 받는 기분이네요 ^^

------------------------------------------------------------
ProgrammingHolic

익명 사용자의 이미지

프로그래밍 숙제를 내고 싶으시다면 뭐 좋습니다만, 디테일에 신경을 써 주셔야지요.

Q1. # 뒤에 $가 나타나지 않을 수 있는가? 만약 그렇다면 어떻게 해야 하는가?

Q2. # 혹은 $가 여러 차례 나타날 수 있는가? 만약 그렇다면 어떻게 해야 하는가?

Q3. #가 나타나지 않을 수 있는가? 만약 그렇다면 어떻게 해야 하는가?

프로그래밍 과제는 답안에서 애매한 부분을 얼버무릴 수가 없기 때문에 문제가 특히나 잘 정의되어 있을 필요가 있지요. 게다가 이런 미묘한 디테일이 난이도에 뚜렷하게 영향을 주는 경우가 많으니까요.

swish95의 이미지

과제라.. 그런 무거운 내용은 아니었는데 ㅋㅋ

그냥 가볍게 생각해주세요

질문에 대한 답은 제가 따로 정하지는 않는게 좋겠습니다.
그런 경우가 나올수 있느냐는 어떤 상황에 저런 코드를 쓰느냐로 결정되고
처리에 대한 경우도 그에 따라 바뀌는 거니까요

과제(?) 를 해결하시는 분이 이렇게 처리 했다 라고 이야기 하는게 더 나을듯 합니다.

------------------------------------------------------------
ProgrammingHolic

황병희의 이미지

Quote:

Q2. # 혹은 $가 여러 차례 나타날 수 있는가? 만약 그렇다면 어떻게 해야 하는가?

# -*- coding: utf-8 -*-
 
raw_data = """\
111
#222
333$
444
555
#666
777
88$8
999
EOL"""
 
data = raw_data.splitlines(False)
 
i = []
j = []
 
for idx in range(0, len(data)):
    if "#" in data[idx]:
        i.append(idx)
    if "$" in data[idx]:
        j.append(idx)
 
        """ $기호 임의의 위치일 경우 예외처리 """
        idx_dollar = data[idx].index("$")
        data[idx] = data[idx][0:idx_dollar+1]
 
result = []
for k, v in zip(i, j):
    result.append("\n".join(data[k:v+1]))
 
print(result) # ['#222\n333$', '#666\n777\n88$']

[우분투 18.04 파여폭스 나비에서 작성했습니다]

--
^고맙습니다 감사합니다_^))//

파이썬3의 이미지

그리고 if __name__ == "__main__": 위에 for 문을 작성한건 좀 이상하네요 그럴거면 "__main__" 행이 없던지 아니면 그 밑에 for 문을 옮기거나 해야 하지 않나 싶습니다. 아직 이 부분은 저도 확실히 의미 파악을 못했습니다. 좀 더 공부해볼께요,,, 조언 감사드립니다^^^

[우분투 18.04 파여폭스 나비에서 작성했어요]

황병희의 이미지

Quote:

그리고 if __name__ == "__main__": 위에 for 문을 작성한건 좀 이상하네요 그럴거면 "__main__" 행이 없던지 아니면 그 밑에 for 문을 옮기거나 해야 하지 않나 싶습니다.

아직 이부분은 저도 확실히 모릅니다. 조언 주셔서 감사드립니다^^^
낮에는 잠시 볏짚단을 우사로 좀 운반하구요,,, 저녁에 다시 뵙도록할께요^^^

[우분투 18.04 파여폭스 나비에서 작성했어요]

--
^고맙습니다 감사합니다_^))//

swish95의 이미지

너무 진지하게 생각하지 않으셔도 됩니다 ^^

이거 참조해보세요 https://pinocc.tistory.com/175

요약하면

a.py

def testFunction (str) :
   print(str)
 
if __name__ == "__main__":
   testFunction("a.py testFunction")

b.py
import a
if __name__ == "__main__":
   a.testFunction("b.py testFunction")

c.py
def testFunction (str) :
   print(str)
 
testFunction("c.py testFunction")

d.py
import c
if __name__ == "__main__":
   c.testFunction("d.py testFunction")

/$ python a.py
a.py testFunction
/$ python b.py
b.py testFunction
/$ python c.py
c.py testFunction
/$ python d.py
c.py testFunction
d.py testFunction

이렇게 되겠죠

------------------------------------------------------------
ProgrammingHolic

황병희의 이미지

한참을 봤지만 복잡한 코드를 짤때에나 쓰겠구나라는 생각이 미치자,, 농사꾼인 제겐 저 __name__ == "__main__" 구절은 평생가도 쓸일이 생기지 않을거 같다는 생각이 들었습니다. 진심으로 소중한 시간 내어주심에 다시 한번 감사드립니다^^^

황병희 드림

[우분투 18.04 파여폭스 나비에서 작성했습니다]

--
^고맙습니다 감사합니다_^))//

황병희의 이미지

swish95 wrote:
1. 문자열을 파일로 받도록 해서 라인단위 검색
- 대용량 파일 대응

이 부분은 정말 한번 시간을 충분히가지고 진지하게 연구해보겠습니다. 정말 감사드립니다^^^

[우분투 18.04 파여폭스 나비에서 작성했습니다]

--
^고맙습니다 감사합니다_^))//

익명 사용자의 이미지

readline 을 사용하는 것보다는 문자 1개씩 읽어들이는게 좋겠습니다.
readline 으로 모두 읽어오면 어차피 문자 1개씩 또 읽어야 되거든요.
sharp_index = -1
dollar_index = -1
new_line_index = -1
변수를 만들고, 파일에서 1문자씩 읽어오면서 '#', '$', '\n' 의 인덱스를 체크하면 되겠네요.
prgname 10 이렇게 하면 # 이후로 10줄 나온다고 칩시다.
10 은 limit 변수에 넣고,
new_line_index 는 1줄마다 인덱스를 갱신해야겠죠.
new_line_count 도 있어야겠네요. new_line_count <= 10

한 바뀌 돌린 다음에,

1. 파일 seek 해서 sharp_index 부터 dollar_index 까지 출력해주면 됩니다.

2. 파일 seek 해서 sharp_index 부터 new_line_index 까지 출력해주면 됩니다.

참 쉽죠잉?

익명 사용자의 이미지

파이선 가는데 루비가 빠질 수 없어서....

#!/usr/bin/ruby
 
linenum  = ARGV[0].to_i
filename = ARGV[1]
 
if ARGV.size != 2 or linenum.to_s != ARGV[0]
  puts "Usage: ruby ./sample.rb linenum filename"
  puts "The linenum should be integer"
  puts "Example: ruby ./sample.rb  0 filename"
  puts "         ruby ./sample.rb 10 filename"
  exit
end
 
sharp_pos      = -1
dollar_pos     = -1
new_line_pos   = -1
new_line_count = 0
 
file = File.open(filename)
 
until file.eof?
 
  c = file.read(1)
 
  case c
  when "\n"
    if (new_line_count < linenum + 1) and (sharp_pos >= 0)
      new_line_pos = file.pos - 1
      new_line_count += 1
    end
  when "#"
    sharp_pos = file.pos - 1 if sharp_pos == -1
  when "$"
    dollar_pos = file.pos - 1 if dollar_pos == -1
  end
 
  break if sharp_pos > 0 and dollar_pos > 0 and new_line_count > linenum
end
 
if (sharp_pos >= 0 and dollar_pos > 0)
  file.seek(sharp_pos, IO::SEEK_SET)
  puts file.read(dollar_pos - sharp_pos + 1)
end
 
puts "--------------"
 
if (sharp_pos >= 0)
  file.seek(sharp_pos, IO::SEEK_SET)
  if (new_line_pos > 0)
    puts file.read(new_line_pos - sharp_pos)
  else
    puts file.readline
  end
end
 
file.close

참 쉽죠잉?

익명 사용자의 이미지

_pos 변수명 대신에 _offset 변수명을 사용했으면 의미가 좀더 와닿았을텐데 아쉽네요

황병희의 이미지

음... 위 루비 산법처럼 행단위로 읽는거대신
한 문자 한 문자를 다 나열후 탐색하는 방식으로 느낌가는대로 다시 한번 구현해봤어요;;;

3.txt wrote:
#아름다운$
#금수강산$
깐돌깐돌
#대한민국$

# -*- coding: utf-8 -*-
 
import sys
 
def make_ch(x):
    f = open(x, "r")
    for line in f:
        for ch in line:
            yield ch
 
    f.close()
 
my_ch = make_ch(sys.argv[1])
 
my_ch_lst = []
 
while True:
    try:
        my_ch_lst.append(next(my_ch))
    except:
        break
 
i = []
j = []
 
for idx in range(0, len(my_ch_lst)):
    if "#" in my_ch_lst[idx]:
        i.append(idx)
    if "$" in my_ch_lst[idx]:
        j.append(idx)
 
result = []
 
for k, v in zip(i, j):
    result.append("".join(my_ch_lst[k:v+1]))
 
print(result) # ['#아름다운$', '#금수강산$', '#대한민국$']

실행결과:
(bionic)soyeomul@localhost:~/111$ python3 3.py 3.txt
['#아름다운$', '#금수강산$', '#대한민국$']

[우분투 18.04 파여폭스 나비에서 작성했습니다]

--
^고맙습니다 감사합니다_^))//

wingback의 이미지

몇일 안온 사이에 이렇게 많은 댓글이.. 대단히 감사합니다.

아직 많이 부족해서 100% 이해는 어렵지만 하나하나 해보면서 제것으로 만들겠습니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.