最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

python實(shí)現(xiàn)excel公式格式化的示例代碼

 更新時(shí)間:2020年12月23日 11:16:41   作者:代碼實(shí)體  
這篇文章主要介紹了python實(shí)現(xiàn)excel公式格式化的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

之前跟一些小伙伴有個(gè)討論:

image-20201214091536248

大概就是很多跟數(shù)據(jù)打交道的朋友都面對(duì)過(guò)很復(fù)雜的excel公式,有時(shí)嵌套層數(shù)特別多,肉眼觀看很容易蒙圈。
有了這樣的需求,我就有了解決問(wèn)題的想法,說(shuō)干就干,于是一個(gè)比較牛逼的excel公式格式化的工具就出現(xiàn)了。

效果體驗(yàn)

先看看效果吧:

=IF(C11>100%*C4,IF(C11<=200%*C4,C11*50%-C4*15%,C11*60%-C4*35%),IF(C11<=C4*50%,C11*30%,C11*40%-C4*5%))

的格式化結(jié)果是:

=IF(
 C11>100%*C4,
 IF(
  C11<=200%*C4,
  C11*50%-C4*15%,
  C11*60%-C4*35%
 ),
 IF(
  C11<=C4*50%,
  C11*30%,
  C11*40%-C4*5%
 )
)

image-20201214165452189

(SMA(MAX(CLOSE-DELAY(CLOSE,1),0),12,1)/SMA(ABS(CLOSE-DELAY(CLOSE,1)),12,1)*100-MIN(SMA(MAX(CLOSE-DELAY(
CLOSE,1),0),12,1)/SMA(ABS(CLOSE-DELAY(CLOSE,1)),12,1)*100,12))/(MAX(SMA(MAX(CLOSE-DELAY(CLOSE,1),0),12,
1)/SMA(ABS(CLOSE-DELAY(CLOSE,1)),12,1)*100,12)-MIN(SMA(MAX(CLOSE-DELAY(CLOSE,1),0),12,1)/SMA(ABS(
CLOSE-DELAY(CLOSE,1)),12,1)*100,12))

的格式化結(jié)果為:

(
 SMA(MAX(CLOSE-DELAY(CLOSE,1),0),12,1)
 /
 SMA(ABS(CLOSE-DELAY(CLOSE,1)),12,1)
 *
 100-MIN(
  SMA(MAX(CLOSE-DELAY(CLOSE,1),0),12,1)
  /
  SMA(ABS(CLOSE-DELAY(CLOSE,1)),12,1)*100,
  12
 )
)
/
(
 MAX(
  SMA(MAX(CLOSE-DELAY(CLOSE,1),0),12,1)
  /
  SMA(ABS(CLOSE-DELAY(CLOSE,1)),12,1)*100,
  12
 )
 -
 MIN(
  SMA(MAX(CLOSE-DELAY(CLOSE,1),0),12,1)
  /
  SMA(ABS(CLOSE-DELAY(CLOSE,1)),12,1)*100,
  12
 )
)
=IF(ROW()>COLUMN(),"",IF(ROW()=COLUMN(),$B15,ROUNDDOWN($B15*INDIRECT(SUBSTITUTE(ADDRESS(1,3+COLUMN()-ROW(),
4),1,"")&56),0)))

的格式化結(jié)果為:

=IF(
 ROW()>COLUMN(),
 "",
 IF(
  ROW()=COLUMN(),
  $B15,
  ROUNDDOWN(
   $B15*INDIRECT(
    SUBSTITUTE(ADDRESS(1,3+COLUMN()-ROW(), 4),1,"")
    &
    56
   ),
   0
  )
 )
)

image-20201214165926821

(文末有體驗(yàn)網(wǎng)址)

不過(guò)接下來(lái),將公布這套格式化程序的完整代碼和開(kāi)發(fā)思想,有技術(shù)能力的小伙伴可以考慮改進(jìn)該代碼。

完整代碼

__author__ = 'xiaoxiaoming'

from collections import deque
import re


class Node:
  def __init__(self, parent=None, tab_size=0):
    self.parent = parent
    self.tab_size = tab_size
    self.data = []

  def is_single_node(self):
    for e in self.data:
      if not isinstance(e, str):
        return False
    return True

  def get_single_text(self):
    return "".join(self.data)


def split_text_blocks(excel_func_text):
  """
  將excel公式字符串,按照一定的規(guī)則切割成數(shù)組
  :param excel_func_text: 被切割的excel公式字符串
  :return: 切割后的結(jié)果
  """
  excel_func_text = excel_func_text.replace('\n', '').replace('\r', '')
  excel_func_text = re.sub(" +", " ", excel_func_text)
  lines = []
  i, j = 0, 0
  while j < len(excel_func_text):
    c = excel_func_text[j]
    if (c == '(' and excel_func_text[j + 1] != ')') or c == ',':
      lines.append(excel_func_text[i:j + 1])
      i = j = j + 1
    elif c == ')' and excel_func_text[j - 1] != '(':
      if i < j:
        lines.append(excel_func_text[i:j])
        i = j # 起始文件塊置于)處
      # 以下代碼查找,如果中間不包含(或),則將)和,之間的文本塊加入到劃分結(jié)果
      k = excel_func_text.find(",", j + 1)
      l = excel_func_text.find("(", j + 1, k)
      m = excel_func_text.find(")", j + 1, k)
      if k != -1 and l == -1 and m == -1:
        lines.append(excel_func_text[i:k + 1])
        i = j = k + 1
      elif j + 1 < len(excel_func_text) and excel_func_text[j + 1] != ')':
        lines.append(")")
        lines.append(excel_func_text[j + 1])
        i = j = j + 2
      else:
        lines.append(")")
        i = j = j + 1
    elif c == '"':
      j = excel_func_text.find('"', j + 1) + 1
    else:
      j += 1
  return lines


blank_char_count = 2


def combine_node(root, text_max_length=60, max_combine_layer=3):
  """
  合并最內(nèi)層的只有純文本子節(jié)點(diǎn)的節(jié)點(diǎn)為單個(gè)文本節(jié)點(diǎn)
  :param root: 被合并的節(jié)點(diǎn)
  :param text_max_length: 合并后的文本長(zhǎng)度不超過(guò)該參數(shù),則應(yīng)用該合并替換原節(jié)點(diǎn)
  :param max_combine_layer: 最大合并層數(shù)
  :return:
  """
  for _ in range(max_combine_layer):
    no_change = True
    stack = deque([root])
    while stack:
      node = stack.pop()
      tmp = {}
      for i, e in enumerate(node.data):
        if isinstance(e, Node):
          if e.is_single_node():
            single_text = e.get_single_text()
            if len(single_text) < text_max_length:
              tmp[i] = single_text
          else:
            stack.append(e)
      for i, e in tmp.items():
        node.data[i] = e
      if len(tmp) != 0:
        no_change = False
    if no_change:
      break


def node_next_line(node):
  for i, e in enumerate(node.data):
    if isinstance(e, str):
      if i == 0 or i == len(node.data) - 1:
        tab = node.tab_size - 1
      else:
        tab = node.tab_size
      yield f"{' ' * blank_char_count * tab}{e}"
    else:
      yield from node_next_line(e)
      

def excel_func_format(excel_func_text, blank_count=2, combine_single_node=True, text_max_length=60,
           max_combine_layer=3):
  """
  將excel公式格式化成比較容易閱讀的格式
  :param excel_func_text: 被格式化的excel公式字符串
  :param blank_count: 最終顯示的格式化字符串的1個(gè)tab用幾個(gè)空格表示
  :param combine_single_node: 是否合并純文本節(jié)點(diǎn),該參數(shù)設(shè)置為T(mén)rue后面的參數(shù)才生效
  :param text_max_length: 合并后的文本長(zhǎng)度不超過(guò)該參數(shù),則應(yīng)用該合并替換原節(jié)點(diǎn)
  :param max_combine_layer: 最大合并層數(shù)
  :return: 格式化后的字符串
  """
  global blank_char_count
  blank_char_count = blank_count
  blocks = split_text_blocks(excel_func_text)
  # print("\n".join(blocks))
  # print('-----------拆分結(jié)果-----------')
  tab_size = 0
  node = root = Node()
  for block in blocks:
    if block.endswith("("):
      tab_size += 1
      child_node = Node(node, tab_size)
      node.data.append(child_node)
      node = child_node
      node.data.append(block)
    elif block.startswith(")"):
      tab_size -= 1
      node.data.append(block)
      node = node.parent
    else:
      node.data.append(block)
  if combine_single_node:
    combine_node(root, text_max_length, max_combine_layer)
  result = [line for line in node_next_line(root)]
  return "\n".join(result)

處理流程淺析

下面都以如下公式作為示例:

=IF(ROW()>COLUMN(),"",IF(ROW()=COLUMN(),$B15,ROUNDDOWN($B15*INDIRECT(SUBSTITUTE(ADDRESS(1,3+COLUMN()-ROW(),
4),1,"")&56),0)))

文本分塊切分

def split_text_blocks(excel_func_text):
  """
  將excel公式字符串,按照一定的規(guī)則切割成數(shù)組
  :param excel_func_text: 被切割的excel公式字符串
  :return: 切割后的結(jié)果
  """
  excel_func_text = excel_func_text.replace('\n', '').replace('\r', '')
  excel_func_text = re.sub(" +", " ", excel_func_text)
  lines = []
  i, j = 0, 0
  while j < len(excel_func_text):
    c = excel_func_text[j]
    if (c == '(' and excel_func_text[j + 1] != ')') or c == ',':
      lines.append(excel_func_text[i:j + 1])
      i = j = j + 1
    elif c == ')' and excel_func_text[j - 1] != '(':
      if i < j:
        lines.append(excel_func_text[i:j])
        i = j # 起始文件塊置于)處
      # 以下代碼查找,如果中間不包含(或),則將)和,之間的文本塊加入到劃分結(jié)果
      k = excel_func_text.find(",", j + 1)
      l = excel_func_text.find("(", j + 1, k)
      m = excel_func_text.find(")", j + 1, k)
      if k != -1 and l == -1 and m == -1:
        lines.append(excel_func_text[i:k + 1])
        i = j = k + 1
      elif j + 1 < len(excel_func_text) and excel_func_text[j + 1] != ')':
        lines.append(")")
        lines.append(excel_func_text[j + 1])
        i = j = j + 2
      else:
        lines.append(")")
        i = j = j + 1
    elif c == '"':
      j = excel_func_text.find('"', j + 1) + 1
    else:
      j += 1
  return lines

s = """=IF(ROW()>COLUMN(),"",IF(ROW()=COLUMN(),$B15,ROUNDDOWN($B15*INDIRECT(SUBSTITUTE(ADDRESS(1,3+COLUMN()-ROW(),
    4),1,"")&56),0))) """

blocks = split_text_blocks(s)
for block in blocks:
  print(block)

的運(yùn)行結(jié)果為:

=IF(
ROW()>COLUMN(),
"",
IF(
ROW()=COLUMN(),
$B15,
ROUNDDOWN(
$B15*INDIRECT(
SUBSTITUTE(
ADDRESS(
1,
3+COLUMN()-ROW(),
 4
),
1,
""
)
&
56
),
0
)
)
)

這端代碼首先替換掉所有的換行符,將多個(gè)空格替換為單個(gè)空格,然后將左右括號(hào)和逗號(hào)作為切分點(diǎn)進(jìn)行切分。

但存在一些特殊情況,例如ROW()和COLUMN()括號(hào)內(nèi)部沒(méi)有任何內(nèi)容,所有這種括號(hào)應(yīng)該作為普通字符處理,另外被""包含的字符串可能包含括號(hào),也應(yīng)該作為普通字符。

構(gòu)建多叉樹(shù)層次結(jié)構(gòu)

設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu):

class Node:
  def __init__(self, parent=None, tab_size=0):
    self.parent = parent
    self.tab_size = tab_size
    self.data = []

parent存儲(chǔ)父節(jié)點(diǎn)的指針,tab_size存儲(chǔ)當(dāng)前節(jié)點(diǎn)的層級(jí),data存儲(chǔ)當(dāng)前節(jié)點(diǎn)的所有數(shù)據(jù)。

構(gòu)建代碼:

tab_size = 0
node = root = Node()
for block in blocks:
  if block.endswith("("):
    tab_size += 1
    child_node = Node(node, tab_size)
    node.data.append(child_node)
    node = child_node
    node.data.append(block)
  elif block.startswith(")"):
    tab_size -= 1
    node.data.append(block)
    node = node.parent
  else:
    node.data.append(block)

構(gòu)建完畢后,這段數(shù)據(jù)在內(nèi)存中的結(jié)構(gòu)(僅展示data)如下:

image-20201214180114188

遍歷打印這顆多叉樹(shù)

def node_next_line(node):
  for i, e in enumerate(node.data):
    if isinstance(e, str):
      if i == 0 or i == len(node.data) - 1:
        tab = node.tab_size - 1
      else:
        tab = node.tab_size
      yield f"{' ' * 2 * tab}{e}"
    else:
      yield from node_next_line(e)
      
result = [line for line in node_next_line(root)]
print("\n".join(result))

結(jié)果:

=IF(
 ROW()>COLUMN(),
 "",
 IF(
  ROW()=COLUMN(),
  $B15,
  ROUNDDOWN(
   $B15*INDIRECT(
    SUBSTITUTE(
     ADDRESS(
      1,
      3+COLUMN()-ROW(),
       4
     ),
     1,
     ""
    )
    &
    56
   ),
   0
  )
 )
)

合并最內(nèi)層的節(jié)點(diǎn)

顯然將最內(nèi)層的node5節(jié)點(diǎn)合并一下閱讀性更好:

image-20201214181546248

首先給數(shù)據(jù)結(jié)構(gòu)增加判斷是否為純文本節(jié)點(diǎn)的方法:

class Node:
  def __init__(self, parent=None, tab_size=0):
    self.parent = parent
    self.tab_size = tab_size
    self.data = []

  def is_single_node(self):
    for e in self.data:
      if not isinstance(e, str):
        return False
    return True

  def get_single_text(self):
    return "".join(self.data)

下面是合并純文本節(jié)點(diǎn)的實(shí)現(xiàn),max_combine_layer決定了合并的最大次數(shù),如果合并后長(zhǎng)度超過(guò)text_max_length參數(shù),則不應(yīng)用這次合并:

from collections import deque

def combine_node(root, text_max_length=60, max_combine_layer=3):
  """
  合并最內(nèi)層的只有純文本子節(jié)點(diǎn)的節(jié)點(diǎn)為單個(gè)文本節(jié)點(diǎn)
  :param root: 被合并的節(jié)點(diǎn)
  :param text_max_length: 合并后的文本長(zhǎng)度不超過(guò)該參數(shù),則應(yīng)用該合并替換原節(jié)點(diǎn)
  :param max_combine_layer: 最大合并層數(shù)
  :return:
  """
  for _ in range(max_combine_layer):
    no_change = True
    stack = deque([root])
    while stack:
      node = stack.pop()
      tmp = {}
      for i, e in enumerate(node.data):
        if isinstance(e, Node):
          if e.is_single_node():
            single_text = e.get_single_text()
            if len(single_text) < text_max_length:
              tmp[i] = single_text
          else:
            stack.append(e)
      for i, e in tmp.items():
        node.data[i] = e
      if len(tmp) != 0:
        no_change = False
    if no_change:
      break

合并一次:

combine_node(root, 100, 1)
result = [line for line in node_next_line(root)]
print("\n".join(result))

結(jié)果:

=IF(
 ROW()>COLUMN(),
 "",
 IF(
  ROW()=COLUMN(),
  $B15,
  ROUNDDOWN(
   $B15*INDIRECT(
    SUBSTITUTE(
     ADDRESS(1,3+COLUMN()-ROW(), 4),
     1,
     ""
    )
    &
    56
   ),
   0
  )
 )
)

合并二次:

combine_node(root, 100, 2)
result = [line for line in node_next_line(root)]
print("\n".join(result))

結(jié)果:

=IF(
 ROW()>COLUMN(),
 "",
 IF(
  ROW()=COLUMN(),
  $B15,
  ROUNDDOWN(
   $B15*INDIRECT(
    SUBSTITUTE(ADDRESS(1,3+COLUMN()-ROW(), 4),1,"")
    &
    56
   ),
   0
  )
 )
)

合并三次:

combine_node(root, 100, 3)
result = [line for line in node_next_line(root)]
print("\n".join(result))

結(jié)果:

=IF(
 ROW()>COLUMN(),
 "",
 IF(
  ROW()=COLUMN(),
  $B15,
  ROUNDDOWN(
   $B15*INDIRECT(SUBSTITUTE(ADDRESS(1,3+COLUMN()-ROW(), 4),1,"")&56),
   0
  )
 )
)

合并三次后的內(nèi)存情況:

image-20201214182511540

體驗(yàn)網(wǎng)址

http://xiaoxiaoming.xyz:8088/excel

不保證永久有效。

到此這篇關(guān)于python實(shí)現(xiàn)excel公式格式化的示例代碼的文章就介紹到這了,更多相關(guān)python excel公式格式化內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • python人工智能算法之決策樹(shù)流程示例詳解

    python人工智能算法之決策樹(shù)流程示例詳解

    這篇文章主要為大家介紹了python人工智能算法之決策樹(shù)流程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • python開(kāi)發(fā)之Docker入門(mén)安裝部署教程

    python開(kāi)發(fā)之Docker入門(mén)安裝部署教程

    這篇文章是一篇入門(mén)篇,主要給大家介紹了關(guān)于python開(kāi)發(fā)中的Docker安裝部署,圖文方式展示了安裝的過(guò)程步驟,有需要的朋友可以參考下
    2021-09-09
  • 使用pytorch搭建AlexNet操作(微調(diào)預(yù)訓(xùn)練模型及手動(dòng)搭建)

    使用pytorch搭建AlexNet操作(微調(diào)預(yù)訓(xùn)練模型及手動(dòng)搭建)

    今天小編就為大家分享一篇使用pytorch搭建AlexNet操作(微調(diào)預(yù)訓(xùn)練模型及手動(dòng)搭建),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-01-01
  • Python去除列表中重復(fù)元素的方法

    Python去除列表中重復(fù)元素的方法

    這篇文章主要介紹了Python去除列表中重復(fù)元素的方法,實(shí)例分析了Python中去除列表重復(fù)元素的使用技巧,需要的朋友可以參考下
    2015-03-03
  • 詳解 Python中LEGB和閉包及裝飾器

    詳解 Python中LEGB和閉包及裝飾器

    這篇文章主要介紹了詳解 Python中LEGB和閉包及裝飾器的相關(guān)資料,主要介紹了函數(shù)作用域和閉包的理解和使用方法及Python中的裝飾器,需要的朋友可以參考下
    2017-08-08
  • 在python中將字符串轉(zhuǎn)為json對(duì)象并取值的方法

    在python中將字符串轉(zhuǎn)為json對(duì)象并取值的方法

    今天小編就為大家分享一篇在python中將字符串轉(zhuǎn)為json對(duì)象并取值的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-12-12
  • 詳細(xì)介紹Scrapy?shell的使用教程

    詳細(xì)介紹Scrapy?shell的使用教程

    Scrapy?shell是一個(gè)非常有用的工具,可以幫助開(kāi)發(fā)者快速地測(cè)試和調(diào)試Scrapy的爬蟲(chóng)代碼,這篇文章主要介紹了詳細(xì)介紹Scrapy?shell的使用,需要的朋友可以參考下
    2023-05-05
  • python 搭建簡(jiǎn)單的http server,可直接post文件的實(shí)例

    python 搭建簡(jiǎn)單的http server,可直接post文件的實(shí)例

    今天小編就為大家分享一篇python 搭建簡(jiǎn)單的http server,可直接post文件的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-01-01
  • 基于Python制作一個(gè)相冊(cè)播放器

    基于Python制作一個(gè)相冊(cè)播放器

    對(duì)于相冊(cè)播放器,大家應(yīng)該都不陌生(用于瀏覽多張圖片的一個(gè)應(yīng)用)。本文將利用Python編寫(xiě)一個(gè)簡(jiǎn)單的相冊(cè)播放器,感興趣的可以學(xué)習(xí)一下
    2022-06-06
  • 簡(jiǎn)述python Scrapy框架

    簡(jiǎn)述python Scrapy框架

    這篇文章主要介紹了python Scrapy框架的相關(guān)資料,幫助大家開(kāi)始學(xué)習(xí)python 爬蟲(chóng),感興趣的朋友可以了解下
    2020-08-08

最新評(píng)論

巴中市| 石林| 尉氏县| 九龙坡区| 六盘水市| 洪江市| 南康市| 调兵山市| 沾化县| 阿克苏市| 修文县| 林口县| 古田县| 黎城县| 通州市| 北海市| 古浪县| 镇远县| 龙州县| 黄浦区| 泰宁县| 武威市| 盐城市| 镇巴县| 平湖市| 循化| 张家口市| 吴桥县| 客服| 牟定县| 安吉县| 上虞市| 卢湾区| 高淳县| 祁连县| 汉阴县| 黑水县| 合江县| 厦门市| 渑池县| 昆明市|